Home > Software design >  Ruby - Filter nested JSON based on uniqueness and push to array
Ruby - Filter nested JSON based on uniqueness and push to array

Time:10-19

I have a json with a main key called section and nested objects of each product within products array.

My json:

{
  "data": [
      {
          "section": 0,
          "products": [
              {
                  "product": "Name 1",
                  "rate": 79.96
              },
              {
                  "product": "Name 2",
                  "rate": 45.96
              }
          ]
      },
      {
          "section": 1,
          "products": [
              {
                  "product": "Name 1",
                  "rate": 86.06
              },
              {
                  "product": "Name 2",
                  "rate": 98.96
              }
          ]
      },
      {
          "section": 2,
          "products": [
              {
                  "product": "Name 1",
                  "rate": 78.95
              },
              {
                  "product": "Name 2",
                  "rate": 24.96
              }
          ]
      },
      {
          "section": 3,
          "products": [
              {
                  "product": "Name 1",
                  "rate": 76.11
              },
              {
                  "product": "Name 2",
                  "rate": 74.96
              }
          ]
      },
      {
          "section": 4,
          "products": [
              {
                  "product": "Name 1",
                  "rate": 76.07
              },
              {
                  "product": "Name 2",
                  "rate": 58.96
              }
          ]
      },
      {
          "section": 5,
          "products": [
              {
                  "product": "Name 1",
                  "rate": 81.15
              },
              {
                  "product": "Name 2",
                  "rate": 15.96
              }
          ]
      }
  ]
}

How am I able to search within the products in all the sections and find the lowest rate for a product with the uniqueness of each product name within the whole data and push to its own object or array?

result example:

{
  "data": [
    {
      "product": "Name 1",
      "rate": 76.07,
      "section": 4
    },
    {
        "product": "Name 2",
        "rate": 15.96,
        "section": 5
    }
  ]
}

I would of course show what I've done so far, but I'm not sure even where and how to start.

Thank you in advance!

CodePudding user response:

The best thing to do is break this down into smaller problems. You can reaily use #each_with_object to build a flat array of "products" and add a :section key to each product info hash.

json[:data].each_with_object([]) { |h, arr|
  h[:products].each { |prod|
    arr << { :section => h[:section], **prod }
  }
}

These can be grouped by product name.

json[:data].each_with_object([]) { |h, arr|
  h[:products].each { |prod|
    arr << { :section => h[:section], **prod }
  }
}.group_by { |h| 
  h[:product] 
}

Now we have a hash containing arrays. We really only need the values.

json[:data].each_with_object([]) { |h, arr|
  h[:products].each { |prod|
    arr << { :section => h[:section], **prod }
  }
}.group_by { |h| 
  h[:product] 
}.values

And for each of these, we need the minimum element by the :rate value.

json[:data].each_with_object([]) { |h, arr|
  h[:products].each { |prod|
    arr << { :section => h[:section], **prod }
  }
}.group_by { |h| 
  h[:product] 
}.values.map { |arr|
  arr.min_by { |prod| prod[:rate] }
}

The result:

[{:section=>4, :product=>"Name 1", :rate=>76.07}, 
 {:section=>5, :product=>"Name 2", :rate=>15.96}]
  • Related