How to merge arrays of hashes based on keys of has

2019-09-13 06:30发布

问题:

I want to merge these two arrays based on uniqueness:

"template_variables": [{
    "info_top": "Some string"
}, {
    "info_bottom": "Other string"
}],


"user_variables": [{
    "info_top": "Default string"
}, {
    "info_bottom": "Other default string"
}, {
    "other_info": "Default number"
}]

So if I start with the user_variables array and add template_variables to it, replacing hashes where matches are found.

My desired output would be:

"new_variables": [{
    "info_top": "Some string"
}, {
    "info_bottom": "Other string"
}, {
    "other_info": "Default number"
}]

I've tried user_variables.merge(template_variables) and variations on that, but that's not suitable for an array of hashes, it seems.

How do I do this?

回答1:

(first_array + second_array).uniq{|hash| hash.keys.first}

but your data structure sucks.



回答2:

If:

hash = { "template_variables":
         [{"info_top":    "Some string"},
          {"info_bottom": "Other string"}],

         "user_variables":
         [{"info_top": "Default string"},
          {"info_bottom": "Other default string"},
          {"other_info": "Default number"}]
       }

Then try this:

values = hash.values.flatten.reverse.inject(&:merge!).map { |k,v| { k => v } }
new_hash = {"new_variables": values} 

returns:

{ :new_variables =>
  [{:other_info => "Default number"},
   {:info_bottom => "Other string"},
   {:info_top => "Some string"}]
}


回答3:

You can simply do something like

 kk = {"aa": [{a: 1}, {b: 2}]}
 jk = {"bb": [{a:3}, {d: 4}]}
 (kk.values+jk.values).flatten.uniq{|hash| hash.keys.first}

Which is similar to Mladen Jablanović post