我需要这个哈希
{"peter" => ["apple", "orange", "mango"], "sandra" => ["flowers", "bike"]}
Run Code Online (Sandbox Code Playgroud)
转换为此数组:
[["peter", "apple"], ["peter", "orange"], ["peter", "mango"], ["sandra", "flowers"], ["sandra", "bike"]]
Run Code Online (Sandbox Code Playgroud)
现在我有了这个解决方案
my_hash.inject([]){|ar, (k,v)| ar << v.map{|c| [k,c]}}.flatten(1)
Run Code Online (Sandbox Code Playgroud)
但我相信这里是更优雅的解决方案与那些zip或transpose魔法:)
你对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"]]
Run Code Online (Sandbox Code Playgroud)
但如果你想使用Enumerable#zip不要让任何人阻止你;-)
h.map { |k, vs| [k].cycle(vs.size).zip(vs) }.flatten(1)
Run Code Online (Sandbox Code Playgroud)
正如@steenslag所说:
h.map { |k, vs| [k].product(vs) }.flatten(1)
Run Code Online (Sandbox Code Playgroud)
所以最后我们可以写:
h.flat_map { |k, vs| [k].product(vs) }
Run Code Online (Sandbox Code Playgroud)