IT박스

해시 값을 변경하는 방법?

itboxs 2020. 7. 16. 19:47
반응형

해시 값을 변경하는 방법?


value해시에서 각각을로 바꾸고 싶습니다 value.some_method.

예를 들어 간단한 해시가 주어진 경우 :

{"a" => "b", "c" => "d"}` 

모든 값은 .upcased 여야 하므로 다음과 같습니다.

{"a" => "B", "c" => "D"}

나는 시도 #collect하고 #map있지만, 항상 그냥 배열을 얻는다. 이것을 할 수있는 우아한 방법이 있습니까?

최신 정보

젠장, 잊어 버렸습니다 : 해시는 인스턴스 변수에 있으며 변경해서는 안됩니다. 변경된 값으로 새 해시가 필요하지만 해당 변수를 명시 적으로 정의한 다음 해시를 반복하여 채우는 것을 선호합니다. 다음과 같은 것 :

new_hash = hash.magic{ ... }

my_hash.each { |k, v| my_hash[k] = v.upcase } 

또는 비파괴 적으로 수행하려면 수정하는 대신 새 해시를 반환하십시오 my_hash.

a_new_hash = my_hash.inject({}) { |h, (k, v)| h[k] = v.upcase; h } 

이 마지막 버전에는 키를 변형 할 수있는 추가 이점이 있습니다.


ruby 2.4.0기본 Hash#transform_values메소드를 사용할 수 있으므로 다음을 수행하십시오 .

hash = {"a" => "b", "c" => "d"}
new_hash = hash.transform_values(&:upcase)
# => {"a" => "B", "c" => "D"}

파괴적인 Hash#transform_values!버전도 있습니다.


값을 수집하여 Array에서 Hash로 다시 변환 할 수 있습니다.

이처럼 :

config = Hash[ config.collect {|k,v| [k, v.upcase] } ]

이것은 그것을 할 것입니다 :

my_hash.each_with_object({}) { |(key, value), hash| hash[key] = value.upcase }

inject장점과는 반대로 블록 내부에서 해시를 다시 반환 할 필요가 없다는 것입니다.


이 기능을 사용해보십시오 :

h = {"a" => "b", "c" => "d"}
h.each{|i,j| j.upcase!} # now contains {"a" => "B", "c" => "D"}.

ActiveSupport v4.2.0 에는 그 방법이 있습니다 . 호출 transform_values되고 기본적으로 각 키-값 쌍에 대한 블록을 실행합니다.

그들이 그것을하고 있기 때문에 each반복하는 것보다 더 좋은 방법은 없다고 생각합니다.

hash = {sample: 'gach'}

result = {}
hash.each do |key, value|
  result[key] = do_stuff(value)
end

최신 정보:

Ruby 2.4.0부터는 기본적으로 #transform_valuesand를 사용할 수 있습니다 #transform_values!.


나는 이런 식으로 뭔가를 :

new_hash = 해시 [* original_hash.collect {| key, value | [키, 값 + 1]}. flatten]

이를 통해 모든 표현을 통해 키 또는 값을 변환 할 수있는 기능을 제공합니다 (물론 비파괴적임).


한 단계 더 나아가 중첩 해시 에서이 작업을 수행 할 수 있습니다. 확실히 이것은 Rails 프로젝트에서 상당한 금액으로 발생합니다.

params 해시가 UTF-8인지 확인하는 코드는 다음과 같습니다.

  def convert_hash hash
    hash.inject({}) do |h,(k,v)|
      if v.kind_of? String
        h[k] = to_utf8(v) 
      else
        h[k] = convert_hash(v)
      end
      h
    end      
  end    

  # Iconv UTF-8 helper
  # Converts strings into valid UTF-8
  #
  # @param [String] untrusted_string the string to convert to UTF-8
  # @return [String] your string in UTF-8
  def to_utf8 untrusted_string=""
    ic = Iconv.new('UTF-8//IGNORE', 'UTF-8')
    ic.iconv(untrusted_string + ' ')[0..-2]
  end  

루비에는 이와 같은 것들에 매우 유용한 tap방법 ( 1.8.7 , 1.9.32.1.0 )이 있습니다.

original_hash = { :a => 'a', :b => 'b' }
original_hash.clone.tap{ |h| h.each{ |k,v| h[k] = v.upcase } }
# => {:a=>"A", :b=>"B"}
original_hash # => {:a=>"a", :b=>"b"}

레일 특정

누군가 to_s가 각 값에 대해 메소드 를 호출해야하고 Rails 4.2 ( transform_values메소드 링크 포함 )를 사용하지 않는 경우 다음을 수행 할 수 있습니다.

original_hash = { :a => 'a', :b => BigDecimal('23.4') }
#=> {:a=>"a", :b=>#<BigDecimal:5c03a00,'0.234E2',18(18)>}
JSON(original_hash.to_json)
#=> {"a"=>"a", "b"=>"23.4"}

참고 : 'json'라이브러리를 사용해야합니다.

참고 2 : 키를 문자열로 바꿉니다.


If you know that the values are strings, you can call the replace method on them while in the cycle: this way you will change the value.

Altohugh this is limited to the case in which the values are strings and hence doesn't answer the question fully, I thought it can be useful to someone.


new_hash = old_hash.merge(old_hash) do |_key, value, _value|
             value.upcase
           end

# old_hash = {"a" => "b", "c" => "d"}
# new_hash = {"a" => "B", "c" => "D"}

참고URL : https://stackoverflow.com/questions/812541/how-to-change-hash-values

반응형