групповой массив объектов - PullRequest
0 голосов
/ 24 сентября 2018

Привет, ребята, у меня есть вопрос о том, как сгруппировать по значению идентификатора ключа и суммировать (значение ключа 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 голосов
/ 24 сентября 2018

Поскольку вы пометили lodash, это так же просто, как (очистить) это:

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

Вы можете использовать сокращение вместо 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>
/11346618/gruppovoi-massiv-obektov

Существует решение Vanilla JS (и более быстрое) для каждого решения lodash.Но это полностью зависит от вас, что вы хотите, вы уже используете lodash или нет.производительность на самом деле важна или чистота кода и ремонтопригодность и обработка всех ключевых случаев и некоторых других факторов.

0 голосов
/ 24 сентября 2018

Вы можете использовать groupBy на основе клавиши id, а затем с помощью map уменьшить с помощью операции sumBy & 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>
0 голосов
/ 24 сентября 2018

Вы можете уменьшить объект и найти объект с таким же 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; }
0 голосов
/ 24 сентября 2018

Вы можете использовать 2 чистых цикла для установки:

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);
0 голосов
/ 24 сентября 2018

Попробуйте:

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);

Этот вопрос похож на: Объединение объектов с одинаковым идентификатором, но суммой значений объектов

...