简体   繁体   中英

How to group by more than one key and sum its values in an array of objects, using Lodash?

In the array below, I want to group by item and reason , then calculate the total quantity :

item_movements = [
  {
    item: "Apple",
    reason: 1,
    quantity: 5
  },
  {
    item: "Banana",
    reason: 2,
    quantity: 10
  },
  {
    item: "Apple",
    reason: 1,
    quantity: 5
  },
  {
    item: "Banana",
    reason: 1,
    quantity: 8
  },
  {
    item: "Apple",
    reason: 2,
    quantity: 3
  },
  {
    item: "Banana",
    reason: 1,
    quantity: 8
  }
];

The result I am trying to achieve is this:

item_totals = [
  {
    item: "Apple",
    1: 10,
    2: 3
  },
  {
    item: "Banana",
    1: 16,
    2: 10
  }
];

I was able to group by item using Loadash like so:

({
  itemMovementbyItem() {
    var result = _(this.item_movements)
      .groupBy(x => x.item)
      .map((value, key) => ({
        item: key,
        item_movements: value
      }))
      .value()

    return result
  }
})

But I am having problems to group a second time by reason .

You could sum the properies directly after grouping by 'item' .

 function itemMovementbyItem(array) { return _(array) .groupBy('item') .map(group => ({ item: group[0].item, 1: _.sumBy(group, o => o.reason === 1 ? o.quantity : 0), 2: _.sumBy(group, o => o.reason === 2 ? o.quantity : 0) })) .value(); } var item_movements = [{ item: "Apple", reason: 1, quantity: 5 }, { item: "Banana", reason: 2, quantity: 10 }, { item: "Apple", reason: 1, quantity: 5 }, { item: "Banana", reason: 1, quantity: 8 }, { item: "Apple", reason: 2, quantity: 3 }, { item: "Banana", reason: 1, quantity: 8 }]; console.log(itemMovementbyItem(item_movements));
 .as-console-wrapper { max-height: 100% !important; top: 0; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

Use reduce to build one object with keys as item. Get Object.values from object.

 const item_movements = [ { item: "Apple", reason: 1, quantity: 5 }, { item: "Banana", reason: 2, quantity: 10 }, { item: "Apple", reason: 1, quantity: 5 }, { item: "Banana", reason: 1, quantity: 8 }, { item: "Apple", reason: 2, quantity: 3 }, { item: "Banana", reason: 1, quantity: 8 } ]; const all = item_movements.reduce((acc, { item, reason, quantity }) => { acc[item] = item in acc ? { ...acc[item], [reason]: (acc[item][reason] || 0) + quantity } : { item, [reason]: quantity }; return acc; }, {}); const item_totals = Object.values(all); console.log(item_totals);

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