Rails将两个数组与哈希结构相结合

时间:2016-08-15 02:59:20

标签: ruby-on-rails arrays ruby hash

我有两个看似相似的数组,其中一部分是重复的,我需要将它们组合起来。

这是第一个数组。

首先

[
      {
             :group_id => "12873",
        :question_sets => [
             {
                  :id => 29435,
                :name => "Question1"
            },
             {
                  :id => 29349,
                :name => "Question2"
            },
            ]
      },
        {
             :group_id => "12876",
        :question_sets => [
             {
                  :id => 29443,
                :name => "Question3"
            }
            ]
      }
]

这是第二个数组

[
      {
             :group_id => "12873",
        :question_sets => [
             {
                  :id => 29435,
                :name => "Question1"
            },
             {
                  :id => 29338,
                :name => "Question4"
            },
            ]
      },
        {
             :group_id => "12888", #(not in first array)
        :question_sets => [
             {
                  :id => 29443,
                :name => "Question3"
            }
            ]
      }
]

我们的想法是将问题集idname合并为相同的group_id,第二个数组中的每个记录都需要合并。如果没有相同的group_id,请创建group_id

结果就像

[
      {
             :group_id => "12873",
        :question_sets => [
             {
                  :id => 29435,
                :name => "Question1"
            },
             {
                  :id => 29349,
                :name => "Question2"
            },
             {
                  :id => 29338,
                :name => "Question4"
            }
            ]
      },
        {
             :group_id => "12876",
        :question_sets => [
             {
                  :id => 29443,
                :name => "Question3"
            }
            ]
      },
      {
             :group_id => "12888",
        :question_sets => [
             {
                  :id => 29443,
                :name => "Question3"
            }
            ]
      }
]

1 个答案:

答案 0 :(得分:1)

如果h1h2是带有密钥:id:name的哈希值,我假设h1[:name] == h2[:name]当且仅当h1[:id] == h2[:id]

如果a1a2等于您的两个数组,则可以执行以下操作。

(a1+a2).group_by { |h| h[:group_id] }.
        map { |k,v| { group_id: k,
                      question_sets: v.flat_map { |g| g[:question_sets] }.uniq } }
  #=> [{:group_id=>"12873",
  #     :question_sets=>[
  #       {:id=>29435, :name=>"Question1"},
  #       {:id=>29349, :name=>"Question2"},
  #       {:id=>29338, :name=>"Question4"}
  #      ]
  #    },
  #    {:group_id=>"12876",
  #     :question_sets=>[{:id=>29443, :name=>"Question3"}]
  #    },
  #    {:group_id=>"12888",
  #     :question_sets=>[{:id=>29443, :name=>"Question3"}]
  #    }
  #   ] 

步骤如下。

a = a1+a2
  #=> [{:group_id=>"12873",
  #     :question_sets=>[
  #       {:id=>29435, :name=>"Question1"},
  #       {:id=>29349, :name=>"Question2"}
  #     ]
  #    },
  #    {:group_id=>"12876",
  #     :question_sets=>[{:id=>29443, :name=>"Question3"}]
  #    },
  #    {:group_id=>"12873",
  #     :question_sets=>[
  #       {:id=>29435, :name=>"Question1"},
  #       {:id=>29338, :name=>"Question4"}
  #     ]
  #    },
  #    {:group_id=>"12888",
  #     :question_sets=>[{:id=>29443, :name=>"Question3"}]
  #    }
  #   ]

b = a.group_by { |h| h[:group_id] }
  #=> {"12873"=>[
  #     {:group_id=>"12873",
  #      :question_sets=>[
  #        {:id=>29435, :name=>"Question1"},
  #        {:id=>29349, :name=>"Question2"}
  #      ]
  #     },
  #     {:group_id=>"12873",
  #      :question_sets=>[
  #        {:id=>29435, :name=>"Question1"},
  #        {:id=>29338, :name=>"Question4"}
  #      ]
  #     }
  #    ],
  #    "12876"=>[
  #      {:group_id=>"12876",
  #       :question_sets=>[{:id=>29443, :name=>"Question3"}]
  #      }
  #    ],
  #    "12888"=>[
  #      {:group_id=>"12888",
  #       :question_sets=>[{:id=>29443, :name=>"Question3"}]
  #      }
  #    ]
  #   }

b.map { |k,v| { group_id: k,
                question_sets: v.flat_map { |g| g[:question_sets] }.uniq } }
  #=> array of hashes shown above.

考虑传递给b块的map的第一个元素,块变量被赋值给它:

k,v = b.first   
k #=> "12873",
v #=> [{:group_id=>"12873",
  #     :question_sets=>[
  #       {:id=>29435, :name=>"Question1"},
  #       {:id=>29349, :name=>"Question2"}
  #     ]
  #    },
  #    {:group_id=>"12873",
  #     :question_sets=>[
  #       {:id=>29435, :name=>"Question1"},
  #       {:id=>29338, :name=>"Question4"}
  #     ] 
  #    }
  #   ]

所以构造哈希的块计算如下:

c = v.flat_map { |g| g[:question_sets] }
  #=> [{:id=>29435, :name=>"Question1"},
  #    {:id=>29349, :name=>"Question2"},
  #    {:id=>29435, :name=>"Question1"},
  #    {:id=>29338, :name=>"Question4"}]
d = c.uniq
  #=> [{:id=>29435, :name=>"Question1"},
  #    {:id=>29349, :name=>"Question2"},
  #    {:id=>29338, :name=>"Question4"}]

所以块返回哈希

{ group_id: k, question_sets: d }
  #=> { group_id: "12873",
  #     question_sets: [
  #       {:id=>29435, :name=>"Question1"},
  #       {:id=>29349, :name=>"Question2"},
  #       {:id=>29338, :name=>"Question4"}
  #     ]
  #   }

其余的计算方法类似。