Как суммировать значения объекта в массиве по некоторому ключу? - PullRequest
0 голосов
/ 16 декабря 2018

Я не могу найти решение этой проблемы.

У меня есть массив:

const taxItems = [{
    taxCode: '430',
    taxAmount: 2,
    ItemTaxPercentage: 20,
    taxCategory: '2'
  },
  {
    taxCode: '430',
    taxAmount: 4,
    ItemTaxPercentage: 20,
    taxCategory: '2'
  },
  {
    taxCode: '431',
    taxAmount: 5,
    ItemTaxPercentage: 20,
    taxCategory: '2'
  },
  {
    taxCode: '430',
    taxAmount: 6,
    ItemTaxPercentage: 20,
    taxCategory: '2'
  }
]

И из этого массива я хочу суммировать все объекты по TaxCode. Я хочу получить такие результаты, какэто:

var results = [{
    taxCode: '430',
    taxAmount: 12,
    ItemTaxPercentage: 20,
    taxCategory: '2'
  },
  {
    taxCode: '431',
    taxAmount: 5,
    ItemTaxPercentage: 20,
    taxCategory: '2'
  }
]

Я пытался использовать lodash:

var results =
lodash(taxItems)
  .groupBy('taxCode')
  .map((objs, key) => ({
      'taxCode': key,
      'taxAmount': lodash.sumBy(objs, 'taxAmount') }))
  .value();

Но это работает только с парой ключ-значение.Я потеряю первоначальную структуру объекта.

Каково будет правильное решение моей проблемы?

Ответы [ 4 ]

0 голосов
/ 18 декабря 2018

Вы также можете решить эту проблему с помощью _.map, _.groupBy и _.mergeWith:

const taxItems = [{ taxCode: '430', taxAmount: 2, ItemTaxPercentage: 20, taxCategory: '2' }, { taxCode: '430', taxAmount: 4, ItemTaxPercentage: 20, taxCategory: '2' }, { taxCode: '431', taxAmount: 5, ItemTaxPercentage: 20, taxCategory: '2' }, { taxCode: '430', taxAmount: 6, ItemTaxPercentage: 20, taxCategory: '2' } ]

const result = _.map(_.groupBy(taxItems, 'taxCode'), x => 
  _.mergeWith(...x, (o,s,k) => k == 'taxAmount' ? o+s : s))

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
0 голосов
/ 16 декабря 2018

Это будет работать.с простым уменьшением.Вам не нужно использовать lodash для этого.

const results = taxItems.reduce(function(sum, taxItem) {

    let index = sum.map(item => item.taxCode).indexOf(taxItem.taxCode);
    if (index == -1) {
        sum.push(taxItem);
    } else {
        sum[index].taxAmount = sum[index].taxAmount + taxItem.taxAmount;
    }

    return sum;
}, []);

//results 
//[{"taxCode":"430","taxAmount":12,"ItemTaxPercentage":20,"taxCategory":"2"}{"taxCode":"431","taxAmount":5,"ItemTaxPercentage":20,"taxCategory":"2"}]
0 голосов
/ 16 декабря 2018

С помощью простого reduce вы можете сделать это следующим образом.

const taxItems = [{
    taxCode: '430',
    taxAmount: 2,
    ItemTaxPercentage: 20,
    taxCategory: '2'
  },
  {
    taxCode: '430',
    taxAmount: 4,
    ItemTaxPercentage: 20,
    taxCategory: '2'
  },
  {
    taxCode: '431',
    taxAmount: 5,
    ItemTaxPercentage: 20,
    taxCategory: '2'
  },
  {
    taxCode: '430',
    taxAmount: 6,
    ItemTaxPercentage: 20,
    taxCategory: '2'
  }
]

let op = Object.values(taxItems.reduce((op,cur)=>{
  if(op[cur['taxCode']]){
    op[cur['taxCode']]['taxAmount']+= cur['taxAmount'];
  } else {
    op[cur['taxCode']] = cur
  }
  return op;
},{}))

console.log(op)
0 голосов
/ 16 декабря 2018

Распределите 1-й объект каждой группы в объект результата, чтобы получить повторяющиеся свойства:

const taxItems = [{"taxCode":"430","taxAmount":2,"ItemTaxPercentage":20,"taxCategory":"2"},{"taxCode":"430","taxAmount":4,"ItemTaxPercentage":20,"taxCategory":"2"},{"taxCode":"431","taxAmount":5,"ItemTaxPercentage":20,"taxCategory":"2"},{"taxCode":"430","taxAmount":6,"ItemTaxPercentage":20,"taxCategory":"2"}];

const results = _(taxItems)
  .groupBy('taxCode')
  .map((objs, taxCode) => ({
      ..._.head(objs),
      taxCode,
      taxAmount: _.sumBy(objs, 'taxAmount') }))
  .value();
  
console.log(results);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
...