哈希到数组转换

fl0*_*00r 2 ruby arrays hash

我需要这个哈希

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

但我相信这里是更优雅的解决方案与那些ziptranspose魔法:)

tok*_*and 5

你对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)

  • [k] .product(vs)代替[k] .cycle(vssize).zip(vs)? (4认同)