Search code examples
javascriptarraysobjectgrouping

Nested Grouping of array of Objects based on properties


I have the data in a file in 5 columns - Location, Item Id, Inventory Number, Bin Number, Quantity.
Sample data-

>[
  {
    "Item ID": 12,
    "Location": "DEL",
    "Inventory Number": 18,
    "Bin Number": 3,
    "Quantity": 250
  },
  {
    "Item ID": 22,
    "Location": "DEL",
    "Inventory Number": 30,
    "Bin Number": 3,
    "Quantity": 50
  },
  {
    "Item ID": 12,
    "Location": "DEL",
    "Inventory Number": 19,
    "Bin Number": 3,
    "Quantity": 250
  },
  {
    "Item ID": 22,
    "Location": "DEL",
    "Inventory Number": 31,
    "Bin Number": 3,
    "Quantity": 50
  }
]

I want to group the data so that all the items for a location are grouped together at first, then all the items are grouped for the location and at last, the inventory number for unique items are grouped.

>{
    "DEL": [
        {
            "itemId": "12",
            "quantity": "500",
            "bins": [
                {
                    "inventorynumber": "18",
                    "binnumber": "3",
                    "quantity": "250"
                },
                {
                    "inventorynumber": "19",
                    "binnumber": "3",
                    "quantity": "250"
                }
            ]
        },
        {
            "itemId": "22",
            "quantity": "100",
            "bins": [
                {
                    "inventorynumber": "30",
                    "binnumber": "3",
                    "quantity": "50"
                },
                {
                    "inventorynumber": "31",
                    "binnumber": "3",
                    "quantity": "50"
                }
            ]
        }
    ]
}

I want to do it in pure JavaScript, I am able to group them separately.
Can anyone help me get the result in desired format?


Solution

  • You could find the inner group.

    const
        data = [{ "Item ID": 12, Location: "DEL", "Inventory Number": 18, "Bin Number": 3, Quantity: 250 }, { "Item ID": 22, Location: "DEL", "Inventory Number": 30, "Bin Number": 3, Quantity: 50 }, { "Item ID": 12, Location: "DEL", "Inventory Number": 19, "Bin Number": 3, Quantity: 250 }, { "Item ID": 22, Location: "DEL", "Inventory Number": 31, "Bin Number": 3, Quantity: 50 }],
        result = data.reduce((r, { "Item ID": itemId, Location: location, "Inventory Number": inventorynumber, "Bin Number": binnumber, Quantity: quantity }) => {
            const temp = (r[location] ??= []).find(q => q.itemId === itemId);
            if (temp) {
                temp.quantity += quantity;
                temp.bins.push({ inventorynumber, binnumber, quantity });
            } else {
                r[location].push({ itemId, quantity, bins: [{ inventorynumber, binnumber, quantity }] });
            }
            return r;
        }, {});
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }