How to merge two arrays and sum values of duplicate objects using lodash

后端 未结 5 1588
走了就别回头了
走了就别回头了 2020-12-19 14:34

There are two arrays:

[
  {\"id\": \"5c5030b9a1ccb11fe8c321f4\", \"quantity\": 1},
  {\"id\": \"344430b94t4t34rwefewfdff\", \"quantity\": 5},
  {\"id\": \"34         


        
相关标签:
5条回答
  • 2020-12-19 14:46

    You can just do this with 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);

    0 讨论(0)
  • 2020-12-19 14:52

    You can do it with plain JavaScript.

    Use Array.reduce() to make an intermediate dictionary by id and accumulate the quantities, then turn it into an array with 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 讨论(0)
  • 2020-12-19 14:57

    Version with additional object keys. The body of the function does not interfere with what object has properties. So sum by "qty" and check by "prop"

    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 讨论(0)
  • 2020-12-19 14:59

    You can use lodash but modern vanilla JS is just as viable and performant. I would imagine the other answers will be using functional methods like reduce, so here's a version that uses a simple for/of loop with find rather than a dictionary lookup which might be longer, but it is a little easier to follow.

    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 讨论(0)
  • 2020-12-19 15:06

    You can use .reduce and .find methods to achieve this.

    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 =  [...arr1, ...arr2].reduce((accumulator, currentValue) => {
      const element = accumulator.find(item => item.id === currentValue.id)
      element ? element.quantity += currentValue.quantity : accumulator.push(currentValue)
      return accumulator
    },[])
    
    console.log(result)

    0 讨论(0)
提交回复
热议问题