简体   繁体   中英

how to merge Hashes in Ruby/Rails

I have a Hash like this, which should be "merged" to its uniq nested values

[
  {
    "slug": "color",
    "values": [{ "slug": "amethyst" },
               { "slug": "coral" }],
  },
  {
    "slug": "color",
    "values": [{ "slug": "amethyst" }],
  },
  {
    "slug": "power-source",
    "values": [{ "slug": "110V"}],
  }
]

at the same time it should count the duplicate values but made uniq in an items array:

 {  "slug": "color",
    "items": [
             {
              "slug": "amethyst",
              "count": 2
             },
             {
              "slug": "coral",
              "count": 1
             }]
 },
{
   "slug": "power-source",
   "items": [
             {
              "slug": "110V",
              "count": 1
             }]
 }
]

is there a "Rails method" to achieve this?

Thank you

I think there's nothing built-in in Rails that allows you to get such a custom requirement, but you can achieve it by playing around with different methods and their return values:

data
  .group_by { |hash| hash[:slug] }
  .transform_values do |values|
    values
      .flat_map { |vals| vals[:values] }
      .group_by { |value| value[:slug] }
      .transform_values(&:count)
  end.map do |slug, items|
    [slug, items.map { |item, count| {slug: item, count: count} }]
  end.map { |slug, items| {slug: slug, items: items} }
  # [{:slug=>"color",
  #   :items=>[{:slug=>"amethyst", :count=>2}, {:slug=>"coral", :count=>1}]},
  #  {:slug=>"power-source", :items=>[{:slug=>"110V", :count=>1}]}]

As you see, you can first group every hash in the array by their slug value, then transform the values that hash contains, mapping and flattening every array by their values key and then grouping to get their total.

After that you can just create the hash with its keys/values you need.

It might simplify the things a bit if you end up with a single hash, whose keys are the "slugs" and contains the items as its values.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM