输入散列可以包含阵列和散列(AoA,AoH,HoH和HoA)的任何组合的嵌套。将哈希元素展平为具有_>
的正确键和分隔符是没有问题的。
但是,当阵列进入图片时我遇到了麻烦,我需要抓住每个元素并将其粘贴到正确的键上,同时继续构建输出。最终输出应该是一维的哈希数组,唯一的区别是每个数组元素。
例如:
如果输入哈希是:
{:x => 333, :y => 13, :z => [1,2,{:zz => [40,50]},[10,20]], :a => {:o => "1", :p => "2"}}
最终结果应为:
`[{:x => 333, :y => 13, :z => 1, :z_>zz => 40, :a_>o => 1, a_>p => 2},
{:x => 333, :y => 13, :z => 1, :z_>zz => 50, :a_>o => 1, a_>p => 2},
{:x => 333, :y => 13, :z => 2, :z_>zz => 40, :a_>o => 1, a_>p => 2},
{:x => 333, :y => 13, :z => 2, :z_>zz => 50, :a_>o => 1, a_>p => 2},
{:x => 333, :y => 13, :z => 10, :z_>zz => 40, :a_>o => 1, a_>p => 2},
{:x => 333, :y => 13, :z => 10, :z_>zz => 50, :a_>o => 1, a_>p => 2},
{:x => 333, :y => 13, :z => 20, :z_>zz => 40, :a_>o => 1, a_>p => 2},
{:x => 333, :y => 13, :z => 20, :z_>zz => 50, :a_>o => 1, a_>p => 2}]`
答案 0 :(得分:2)
这是漫长而复杂的,但至少它有效:
my_hash = {:x => 333, :y => 13, :z => [1,2,{:zz => [40,50]},[10,20]], :a => {:o => "1", :p => "2"}}
# Create Recursive function to get values:
def advance_hash_flattener(input, parent=[])
case input
when Hash then input.flat_map{|key, val|
advance_hash_flattener(val, parent+[key])}
when Array then input.flat_map{|x| advance_hash_flattener(x, parent)}
else [parent.join('_>'), input]
end
end
#Some small transformations for the last step:
first_step = advance_hash_flattener(my_hash)
.each_slice(2)
.group_by{|x| x.first}
.map{|x| [x.first, x.last.map(&:last)]}
p first_step #=> [["x", [333]], ["y", [13]], ["z", [1, 2, 10, 20]], ["z_>zz", [40, 50]], ["a_>o", ["1"]], ["a_>p", ["2"]]]
# Create an array of Hashes:
final_array = [Hash.new]
first_step.each do |key,values|
new = []
values.each do |val|
if final_array.first.key?(key)
final_copy = final_array.map{|x|x.clone}
final_copy.each{|x| x[key] = val}
new += final_copy
else
final_array.each{|x| x[key] = val}
end
end
final_array += new
end
# result stored in final_array