Eu gostaria de substituir cada value
um com um hash value.some_method
.
Por exemplo, para um hash simples:
{"a" => "b", "c" => "d"}`
todo valor deve ser .upcase
d, para que se pareça com:
{"a" => "B", "c" => "D"}
Eu tentei #collect
e #map
sempre recuperei as matrizes. Existe uma maneira elegante de fazer isso?
ATUALIZAR
Porra, eu esqueci: O hash está em uma variável de instância que não deve ser alterada. Eu preciso de um novo hash com os valores alterados, mas preferiria não definir essa variável explicitamente e fazer um loop sobre o hash que a preenchia. Algo como:
new_hash = hash.magic{ ... }
Respostas:
ou, se você preferir fazê-lo de forma não destrutiva e retornar um novo hash em vez de modificar
my_hash
:Esta última versão possui o benefício adicional de que você também pode transformar as chaves.
fonte
each_with_object
é uma versão mais conveniente deinject
quando você não quer terminar o bloco com o hash:my_hash.each_with_object({}) {|(k, v), h| h[k] = v.upcase }
a_new_hash = Hash[ my_hash.map { |k, v| [k, v.upcase] } ]
.to_h
Desde que
ruby 2.4.0
você pode usar oHash#transform_values
método nativo :Há também uma
Hash#transform_values!
versão destrutiva .fonte
Você pode coletar os valores e convertê-lo de Matriz em Hash novamente.
Como isso:
fonte
Isso fará isso:
Em oposição à
inject
vantagem, você não precisa devolver o hash novamente dentro do bloco.fonte
Tente esta função:
fonte
Há um método para isso no ActiveSupport v4.2.0. É chamado
transform_values
e basicamente apenas executa um bloco para cada par de valores-chave.Já que eles estão fazendo isso com um
each
, acho que não há maneira melhor do que fazer um loop.Atualizar:
Desde o Ruby 2.4.0, você pode usar nativamente
#transform_values
e#transform_values!
.fonte
Você pode dar um passo adiante e fazer isso em um hash aninhado. Certamente isso acontece com os projetos Rails.
Aqui está um código para garantir que um hash de params esteja no UTF-8:
fonte
Eu faço algo assim:
Isso fornece a você as facilidades para transformar a chave ou o valor por meio de qualquer expressão também (e é não destrutivo, é claro).
fonte
Ruby tem o
tap
método ( 1.8.7 , 1.9.3 e 2.1.0 ) que é muito útil para coisas como esta.fonte
Rails-specific
Caso alguém precise chamar o
to_s
método para cada um dos valores e não esteja usando o Rails 4.2 (que inclui o link dotransform_values
método ), você pode fazer o seguinte:Nota: O uso da biblioteca 'json' é necessário.
Nota 2: Isso também transformará chaves em strings
fonte
Se você souber que os valores são cadeias, você pode chamar o método de substituição neles enquanto estiver no ciclo: dessa forma, você alterará o valor.
Embora isso seja limitado ao caso em que os valores são cadeias de caracteres e, portanto, não responde totalmente à pergunta, achei que poderia ser útil a alguém.
fonte
fonte