Johnny Daves
Johnny Daves

Reputation: 15

How to create an object map of items with the most quantity from array of objects?

New to JavaScript and this is my first post. So I have this array of objects:

  var allOrders = [
        {
            id: 1,
            order: [
                { itemName: "Shoes", quantity: 1 },
                { itemName: "Socks", quantity: 3 },
                { itemName: "Sandals", quantity: 5 },
                { itemName: "Shirts", quantity: 1 },
            ],
        },
        {
            id: 2,
            order: [
                { itemName: "Hats", quantity: 1 },
                { itemName: "Shoes", quantity: 3 },
                { itemName: "Sandals", quantity: 5 },
                { itemName: "Shirts", quantity: 1 },
            ],
        },
 ]

I have done a nested loop to access all the itemName and quantity.

for (let i = 0; i < allOrders.length; i++) {
  let orders = allOrders[i].order

  for (let j = 0; j < orders.length; j++) {
    let itemName = orders[j].itemName;
    let quantity = orders[j].quantity;
  }
}

What I want to do is return some sort of object mapper that will count the total number of quantity for each unique item in descending order like this

{
   Sandals: 10,
   Shoes: 4,
   Socks: 3,
   Shirts: 3,
   Hats: 1
}

Thank you!

Upvotes: 0

Views: 248

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 371198

Reduce into an object indexed by itemName, then sort its entries to create a sorted object using Object.fromEntries:

var allOrders = [
{
id: 1,
order: [
    { itemName: "Shoes", quantity: 1 },
    { itemName: "Socks", quantity: 3 },
    { itemName: "Sandals", quantity: 5 },
    { itemName: "Shirts", quantity: 1 },
],
},
{
id: 2,
order: [
    { itemName: "Hats", quantity: 1 },
    { itemName: "Shoes", quantity: 3 },
    { itemName: "Sandals", quantity: 5 },
    { itemName: "Shirts", quantity: 1 },
],
},
];

const unordered = allOrders.reduce((a, { order }) => {
  order.forEach(({ itemName, quantity }) => {
    a[itemName] = (a[itemName] || 0) + quantity;
  });
  return a;
}, {});
const ordered = Object.fromEntries(
  Object.entries(unordered).sort(
    (a, b) => b[1] - a[1]
  )
);
console.log(ordered);

Do keep in mind that object property iteration order is only guaranteed in ES6+ environments if you use certain iteration methods, like Object.getOwnPropertyNames, or Reflect.ownKeys. (If you use other methods like for..in or Object.keys or Object.entries, the order of the keys is implementation-defined)

Upvotes: 1

Related Questions