2011-06-01 133 views
1

說我有這樣的紅寶石哈希與數組值

{"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} 

回答

3

你可以用一個簡單的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] } 
+0

好點啊。你贏了;) – 2011-06-01 02:16:10

+0

@Ryan:你應該離開你的了,如果你想離開原作,這是合理的解決方案。 – 2011-06-01 02:23:55

+0

等一下,我們可以改變嗎?那麼該死:) – zetetic 2011-06-01 02:29:36

1

也許更有吸引力的使用injectHash#merge是你的朋友:

hash = {"k1"=>["v1"], "k2"=>["v2"], "k3"=>["v3"], "k4"=>["v4"]} 
hash.inject({}) {|r,a| r.merge(a.first=>a.last.first)} 
+1

使用'| r,(k,v)|'會更有吸引力,我在這個符號中添加了幾個選項來回答我的問題。 – 2011-06-01 02:43:21

+0

嗯,這個對我來說實際上讀起來有點醜陋=) – maerics 2011-06-01 02:59:25

+0

@mu:不錯,我不知道你可以通過這種方式獲得關鍵/價值的參數。 – zetetic 2011-06-01 03:25:12

8

一定程度上比你的「注入」的解決方案少醜:

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

由於@the鐵皮人在評論中指出,如果你的價值陣列可能有不止一個元素那麼你就需要做一些事情略有不同,它的工作如預期:

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

+1。太棒了。 – zetetic 2011-06-01 03:27:36

+0

如果值數組有多個元素,它將不起作用。 – 2011-06-01 05:05:23

+1

只適用於1.8,其中'map'返回'Array'。在1.9中,你需要'Hash [* h1.map.to_a.flatten]',因爲'map'給你一個'Enumerator'。否則,非常酷。 – Amadan 2011-06-01 08:22:08

1
>> 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

組合來自@ tokland的答案Hash[h.map { |k, v| [k, v.first] }]語法與@畝的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]}]