我需要这个哈希
{"peter" => ["apple", "orange", "mango"], "sandra" => ["flowers", "bike"]}
转换成这个数组:
[["peter", "apple"], ["peter", "orange"], ["peter", "mango"], ["sandra", "flowers"], ["sandra", "bike"]]
现在我得到了这个解决方案
my_hash.inject([]){|ar, (k,v)| ar << v.map{|c| [k,c]}}.flatten(1)
但我相信这里有更优雅的解决方案,使用那些 zip
或 transpose
magick :)
最佳答案
您对 Enumerable#inject
解决方案的怀疑是正确的。在 Ruby 中,inject/reduce
在某种程度上被滥用了,我们必须小心并选择正确的抽象(map、select、zip、flatten...),如果它们适合手头的问题。在这种情况下:
h = {"peter" => ["apple", "orange", "mango"], "sandra" => ["flowers", "bike"]}
h.map { |k, vs| vs.map { |v| [k, v] } }.flatten(1)
#=> [["peter", "apple"], ["peter", "orange"], ["peter", "mango"], ["sandra", "flowers"], ["sandra", "bike"]]
但是如果你想使用 Enumerable#zip
不要让任何人阻止你 ;-)
h.map { |k, vs| [k].cycle(vs.size).zip(vs) }.flatten(1)
正如@steenslag 所说,还有:
h.map { |k, vs| [k].product(vs) }.flatten(1)
所以最后我们可以这样写:
h.flat_map { |k, vs| [k].product(vs) }
关于ruby - 哈希到数组转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7513108/