2011-03-02 90 views
49

我有兩個數組:合併兩個數組到哈希

members  = ["Matt Anderson", "Justin Biltonen", "Jordan Luff", "Jeremy London"] 
instruments = ["guitar, vocals", "guitar", "bass", "drums"] 

我想要做的就是將這些使得所得到的數據結構是像這樣一個Hash:

{"Matt Anderson"=>["guitar", "vocals"], "Justin Biltonen"=>"guitar", "Jordan Luff"=>"bass", "Jeremy London"=>"drums"} 

請注意,「Matt Anderson」的值現在是數組而不是字符串。任何Ruby的巫師都在乎這個鏡頭?

我知道Hash[*members.zip(instruments).flatten]將它們組合幾乎的我想了解打開「吉他,主唱」字符串爲數組第一種方式,但什麼?謝謝。

+2

沒有zip功能嗎? – 2011-03-02 23:45:13

+1

不需要問題示例中的'*'和'.flatten'。 'Hash [members.zip(instruments)]'給出與'Hash [* members.zip(instruments).flatten]'相同的結果' – nohat 2011-03-03 00:04:51

+1

我會將它變成'{...「Justin Biltonen」=> [「guitar 「] ...}'因爲它會使工作更容易 - 在這種情況下,map/zip/split/Hash將提供一個很好的解決方案。 – 2011-03-03 00:20:33

回答

44

使用mapsplit到儀器字符串轉換成數組:

instruments.map {|i| i.include?(',') ? (i.split /, /) : i} 

然後使用Hash[]zip結合membersinstruments

Hash[members.zip(instruments.map {|i| i.include?(',') ? (i.split /, /) : i})] 

通用電氣牛逼

{"Jeremy London"=>"drums", 
"Matt Anderson"=>["guitar", "vocals"], 
"Jordan Luff"=>"bass", 
"Justin Biltonen"=>"guitar"} 

如果你不介意的單項列表也數組,你可以使用這個簡單的解決方案:

Hash[members.zip(instruments.map {|i| i.split /, /})] 

它給你這樣的:

{"Jeremy London"=>["drums"], 
"Matt Anderson"=>["guitar", "vocals"], 
"Jordan Luff"=>["bass"], 
"Justin Biltonen"=>["guitar"]} 
+0

+1但我無法想象你的第一個解決方案是什麼。爲什麼散列返回一個字符串或數組?我會隨時選擇你的第二個解決方案。(「steenslag」=> []) – steenslag 2011-03-03 01:29:48

+4

@steenslag它對於問題的要求是很好的:-) – nohat 2011-03-03 14:32:58

1
h = {} 
members.each_with_index do |el,ix| 
    h[el] = instruments[ix].include?(",") ? instruments[ix].split(",").to_a : instruments[ix] 
end 
h 
+0

其實,我錯了,你需要檢查,如果你需要一個單一的條目而不是包含一個字符串的數組的字符串 – macarthy 2011-03-02 23:50:14

0
h = {} 

members.each_with_index {|item, index| 
    h.store(item,instruments[index].split) 
} 
1
members.inject({}) { |m, e| t = instruments.delete_at(0).split(','); m[e] = t.size > 1 ? t : t[0]; m } 

如果您不關心結果中的1單元陣列,您可以使用:

members.inject({}) { |m, e| m[e] = instruments.delete_at(0).split(','); m } 
86

正如Rafe Kettler發佈的那樣,使用zip是最好的選擇。

Hash[members.zip(instruments)] 
+5

我見過的最簡單的解決方案。 – 2012-10-05 02:45:06

+3

這個答案是錯誤的。 OP要求'{「Matt Anderson」=> [「吉他」,「vocals」],...}',但是這個答案返回'{「Matt Anderson」=>「guitar,vocals」,...} – nohat 2014-01-28 02:53:28

+0

你怎麼能做同樣的事情,但命名密鑰?即'{[:member =>'Jeremy London,:樂器=>'鼓'],[:member =>'other guy',:instrument =>'guitar'] ... – kakubei 2014-04-08 11:57:12

7

例01

k = ['a', 'b', 'c'] 
v = ['aa', 'bb'] 
h = {} 

k.zip(v) { |a,b| h[a.to_sym] = b } 
# => nil 

p h 
# => {:a=>"aa", :b=>"bb", :c=>nil} 

例02

k = ['a', 'b', 'c'] 
v = ['aa', 'bb', ['aaa','bbb']] 
h = {} 

k.zip(v) { |a,b| h[a.to_sym] = b } 
p h 
# => {:a=>"aa", :b=>"bb", :c=>["aaa", "bbb"]} 
+0

非常簡單,謝謝 – 2016-06-01 06:32:04

3

這是你想要做什麼最好的和最徹底的方法。

Hash[members.zip(instruments.map{|i| i.include?(',') ? i.split(',') : i})] 

Enjoy!