Как объединить два массива и суммировать значения дубликатов объектов, используя lodash - PullRequest
0 голосов
/ 26 февраля 2019

Существует два массива:

[
  {"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 1},
  {"id": "344430b94t4t34rwefewfdff", "quantity": 5},
  {"id": "342343343t4t34rwefewfd53", "quantity": 3}
]

и

[
  {"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 2},
  {"id": "344430b94t4t34rwefewfdff", "quantity": 1}
]

Как объединить их в одну сумму суммирования?

[
  {"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 3},
  {"id": "344430b94t4t34rwefewfdff", "quantity": 6},
  {"id": "342343343t4t34rwefewfd53", "quantity": 3}
]

Один из них может бытьиногда пусто

Ответы [ 4 ]

0 голосов
/ 01 марта 2019

Версия с дополнительными объектными ключами.Тело функции не влияет на то, какой объект обладает свойствами.Таким образом, сумма по "кол-во" и проверка по "опора"

var first = [ 
  {quantity:100, id:1, variantId: 1}, 
  {quantity:300, id:2, variantId: 2, propA: 'aaa'},

];

var second = [
  {quantity:100, id:1, variantId: 1},
  {quantity:200, id:2, variantId: 2, propB: true}, 
  {quantity:300, id:3, variantId: 3, propC: 'ccc'}, 
]

function mergeArrays(arrayOfArrays, propToCheck, propToSum) {
    let sum = [];
    [].concat(...arrayOfArrays).map(function(o) {
        
        let existing = sum.filter(function(i) { return i[propToCheck] === o[propToCheck] })[0];
    
        if (!existing) {

            sum.push(o);
        } else {

            existing[propToSum] += o[propToSum];
            
            let copyProps = Object.keys(o).filter(obj => {
                  return existing[obj] !== o[obj]
            }).map(val => (val !== propToSum) ? existing[val] = o[val] : null)
        }
             
    });

    return sum;
}

console.log(mergeArrays([first, second], 'variantId', 'quantity'))
0 голосов
/ 26 февраля 2019

Вы можете сделать это с простым JavaScript.

Используйте Array.reduce(), чтобы создать промежуточный словарь по идентификатору и накапливать количества, а затем превратить его в массив с Object.values():

const arr1 = [
  {"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 1},
  {"id": "344430b94t4t34rwefewfdff", "quantity": 5},
  {"id": "342343343t4t34rwefewfd53", "quantity": 3}
];
const arr2 = [
  {"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 2},
  {"id": "344430b94t4t34rwefewfdff", "quantity": 1}
];

const result = Object.values([...arr1, ...arr2].reduce((acc, { id, quantity }) => {
  acc[id] = { id, quantity: (acc[id] ? acc[id].quantity : 0) + quantity  };
  return acc;
}, {}));

console.log(result);
0 голосов
/ 26 февраля 2019

Вы можете использовать lodash, но современный ванильный JS так же жизнеспособен и эффективен.Я полагаю, что другие ответы будут использовать функциональные методы, такие как reduce, так что вот версия, которая использует простой цикл for/of с find, а не поиск по словарю, который может быть длиннее, но этонемного легче следовать.

const arr1 = [{"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 1}, {"id": "344430b94t4t34rwefewfdff", "quantity": 5}, {"id": "342343343t4t34rwefewfd53", "quantity": 3}];
const arr2 = [{"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 2}, {"id": "344430b94t4t34rwefewfdff", "quantity": 1}];

function merge(arr1, arr2) {

  // Merge the arrays, and set up an output array.
  const merged = [...arr1, ...arr2];
  const out = [];

  // Loop over the merged array
  for (let obj of merged) {

    // Destructure the object in the current iteration to get
    // its id and quantity values
    const { id, quantity } = obj;

    // Find the object in out that has the same id
    const found = out.find(obj => obj.id === id);

    // If an object *is* found add this object's quantity to it...
    if (found) {
      found.quantity += quantity;

    // ...otherwise push a copy of the object to out
    } else {
      out.push({ ...obj });
    }
  }
  
  return out;

}

console.log(merge(arr1, arr2));
0 голосов
/ 26 февраля 2019

Вы можете просто сделать это с помощью Reduce:

let a1 = [
  {"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 2},
  {"id": "344430b94t4t34rwefewfdff", "quantity": 1}
];

let a2 = [
  {"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 1},
  {"id": "344430b94t4t34rwefewfdff", "quantity": 5},
  {"id": "342343343t4t34rwefewfd53", "quantity": 3}
];

let result = Object.values(a1.concat(a2).reduce((acc, v) => {
   if (!acc[v.id]) {
       acc[v.id] = {id: v.id, quantity: 0};
   }
   acc[v.id].quantity += v.quantity;
   return acc;
}, {}));

console.log("Results: ", result);
...