나는 각을 교체하고 싶습니다 value
과 함께 해시 value.some_method
.
예를 들어 간단한 해시가 주어진 경우 :
{"a" => "b", "c" => "d"}`
모든 값은 .upcase
d 여야 하므로 다음과 같습니다.
{"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_values
및 #transform_values!
.
답변
한 단계 더 나아가 중첩 된 해시에서이 작업을 수행 할 수 있습니다. 확실히 이것은 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