对象组数组

时间:2018-09-24 08:32:02

标签: javascript grouping lodash

大家好,我想知道如何按密钥ID值分组并求和(密钥harga值和密钥qty值) 以下是对象数组:

order: [
  {
    id: 4,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 8000,
    qty: 1
  },
  {
    id: 4,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 8000,
    qty: 1
  }
]

我无法实现的目标是这样的:

order:[
   {
     id: 4,
     idkatg: 2,
     kategori: 'minuman',
     nmprod: 'es mambo',
     harga: 14000,
     qty: 2
   }
]

也许有使用lodash的解决方案吗?

5 个答案:

答案 0 :(得分:1)

尝试一下:

const order = [
  {
    id: 4,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 8000,
    qty: 1
  },
  {
    id: 4,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 8000,
    qty: 1
  }
];

const newOrder = [];

for (const index in order) {
  const item = order[index];
  const itemInNewOrder = newOrder.filter(i => i.id === item.id)[0];

  if (itemInNewOrder) {
    itemInNewOrder.harga += item.harga;
  } else {
    newOrder.push(item);
  }
}

console.log(newOrder);

此问题类似于:Merge objects with the same id but sum values of the objects

答案 1 :(得分:1)

您可以缩小对象并找到具有相同id的对象,然后进行更新。否则,将实际对象推入结果集中。

如果需要,您可以使用

r.push(Object.assign({}, o));

var order = [{ id: 4, idkatg: 2, kategori: 'minuman', nmprod: 'es mambo', harga: 8000, qty: 1 }, { id: 4, idkatg: 2, kategori: 'minuman', nmprod: 'es mambo', harga: 8000, qty: 1 }];

order = order.reduce((r, o) => {
   var temp = r.find(({ id }) => id === o.id);
   if (temp) {
       ['harga', 'qty'].forEach(k => temp[k] += o[k]);
   } else {
       r.push(o);
   }
   return r;
}, []);

console.log(order);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:1)

您可以使用2个纯for循环来设置:

var order = [
  {
    id: 4,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 8000,
    qty: 1
  },
  {
    id: 4,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 8000,
    qty: 1
  },
  {
    id: 5,
    idkatg: 3,
    kategori: '5 minuman',
    nmprod: '5 es mambo',
    harga: 5000,
    qty: 3
  },
  {
    id: 5,
    idkatg: 3,
    kategori: '5 minuman',
    nmprod: '5 es mambo',
    harga: 4000,
    qty: 2
  },
  {
    id: 6,
    idkatg: 4,
    kategori: '6 minuman',
    nmprod: '6 es mambo',
    harga: 6000,
    qty: 2
  }
];

var result = [];
result.push(order[0]);
for (var i=1; i<order.length; i++){
  //compare object order[i] with order[0] ... order[n]
  var flagExist = false;
  for (var j=0; j<i; j++){
    if(order[j].id === order[i].id){
      flagExist = true;
      //set for object old, with new qty and harga
      order[j].qty = order[i].qty + order[j].qty;
      order[j].harga = order[i].harga + order[j].harga;
      break;
    }
  }
  if (flagExist == false)
    result.push(order[i]);
}
console.log(result);

答案 3 :(得分:1)

您可以基于groupBy键使用id,然后使用mapsumBy操作使用fromPairs减少操作。

let order = [ { id: 4, idkatg: 2, kategori: 'minuman', nmprod: 'es mambo', harga: 8000, qty: 1 }, { id: 4, idkatg: 2, kategori: 'minuman', nmprod: 'es mambo', harga: 8000, qty: 1 } ],
    result = _(order).groupBy('id').map((o,k) =>
      ({...o[0], ..._.fromPairs(_(['qty','harga']).map(k => [k,_.sumBy(o,k)]).value())})).value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

答案 4 :(得分:1)

由于您已经标记了lodash,因此就像(更干净的)标记一样简单:

_(order).groupBy('id').map(a=>({...a[0], harga: _.sumBy(a, 'harga'), qty: _.sumBy(a, 'qty')})).value()

如果要在单次迭代中求和,则可以使用reduce而不是2 sumBy(但是,使用lodash实际上并不希望以更少的迭代来寻找更快的解决方案

let order = [
  {
    id: 4,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 8000,
    qty: 1
  },
  {
    id: 3,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 2000,
    qty: 1
  },
  {
    id: 4,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 8000,
    qty: 1
  },
  {
    id: 5,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 6000,
    qty: 1
  },
  {
    id: 5,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 9000,
    qty: 1
  }
];

let res =_(order).groupBy('id').map(a=>({...a[0], harga: _.sumBy(a, 'harga'), qty: _.sumBy(a, 'qty')})).value()

console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
https://stackoverflow.com/questions/52475365/group-array-of-objects/52475751#

每个lodash解决方案都有Vanilla JS解决方案(并且速度更快)。但这完全取决于您想要什么,您是否已经使用lodash。性能实际上是最重要的代码或最简洁的代码,可维护性以及处理所有极端情况和其他一些因素。