Рубиновый хеш со значениями массива - PullRequest
1 голос
/ 01 июня 2011

Скажем, у меня есть такой хеш

{"k1"=>["v1"], "k2"=>["v2"], "k3"=>["v3"], "k4"=>["v4"]}

И я хочу, чтобы он выглядел так:

{"k1"=>"v1", "k2"=>"v2", "k3"=>"v3", "k4"=>"v4"}

Есть ли более простой способ сделать это, чем этот уродливый inject?

h1 = {"k1"=>["v1"], "k2"=>["v2"], "k3"=>["v3"], "k4"=>["v4"]}
h2 = h1.inject({}){|h,v| h[v.first]=v.last.first; h}

Ответы [ 5 ]

8 голосов
/ 01 июня 2011

Несколько менее уродливо, чем ваше решение для «инъекции»:

h1 = {"k1"=>["v1"], "k2"=>["v2"], "k3"=>["v3"], "k4"=>["v4"]}
h2 = Hash[*h1.map.flatten]
h2 # => {"k1"=>"v1", "k2"=>"v2", "k3"=>"v3", "k4"=>"v4"}

Как отметил @ The Tin Man в комментарии, если в ваших массивах значений может быть более одного элемента, вам потребуетсячто-то немного другое, чтобы оно работало как положено:

h2 = Hash[*h1.map{|k,v|[k,v[0]]}.flatten]
h2 # => {"k1"=>"v1", "k2"=>"v2", "k3"=>"v3", "k4"=>"v4"}
3 голосов
/ 01 июня 2011

Вы можете изменить его на месте с помощью простого each:

h = {"k1"=>["v1"], "k2"=>["v2"], "k3"=>["v3"], "k4"=>["v4"]}
h.each { |k,v| h[k] = v[0] }

Или, если вы хотите сделать копию, вы можете использовать очиститель inject, например:

flatter_h = h.inject({ }) { |x, (k,v)| x[k] = v[0]; x }

Или, если у вас есть each_with_object (например, Rails или Ruby 1.9):

flatter_h = h.each_with_object({ }) { |(k,v), x| x[k] = v[0] }
1 голос
/ 01 октября 2011

Сочетая синтаксис Hash[h.map { |k, v| [k, v.first] }] из ответа @ tokland с синтаксисом деструктуризации массива, представленным в @ mu's h.inject({ }) { |x, (k,v)| x[k] = v[0]; x }, я пришел к тому, что я считаю самым чистым решением:

h1 = {"k1"=>["v1"], "k2"=>["v2"], "k3"=>["v3"], "k4"=>["v4"]}
h2 = Hash[h1.map{|k,(v)| [k, v]}]
1 голос
/ 01 июня 2011
>> h = {"k1"=>["v1"], "k2"=>["v2"], "k3"=>["v3"], "k4"=>["v4"]}
>> Hash[h.map { |k, vs| [k, vs.first] }]
=> {"k1"=>"v1", "k2"=>"v2", "k3"=>"v3", "k4"=>"v4"}
1 голос
/ 01 июня 2011

Возможно, более привлекательное использование inject. Hash#merge твой друг:

hash = {"k1"=>["v1"], "k2"=>["v2"], "k3"=>["v3"], "k4"=>["v4"]}
hash.inject({}) {|r,a| r.merge(a.first=>a.last.first)}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...