2011-03-02 115 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!