0

输入哈希可以包含任何数组和哈希(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}]`
4

1 回答 1

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
于 2013-10-22T14:00:34.270 回答