2013-08-07 50 views
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}]` 
+0

我已經使用遞歸哈希小平坦化了輸入哈希恩。如果該值是一個數組,則通過將{theKey => theKeysValue}推入數組以供稍後訪問進行循環。 – discodude

回答

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