Merge Array of Objects by Property using Lodash

后端 未结 7 1573
北恋
北恋 2020-12-01 06:25

I have two arrays of objects that represent email addresses that have a label and a value:

var original = [
  {
    label: \'private\',
    value: \'private@         


        
相关标签:
7条回答
  • 2020-12-01 06:50

    Perhaps a bit late, but all the solutions I have seen don't join both arrays correctly, they use one of the arrays to loop on and any excess elements in the second array don't get added (assuming this is what is required).

    The right way is to sort both arrays and move forward within both arrays, merging the matches elements and adding the missing elements from both arrays. Please find full solution below. This also takes O(n+m) which is the best you can get (without the computational costs for sort itself). In my code I already got the data sorted from the database.

    function mergeObjectsBasedOnKey(array1, array2, compareFn, mergeFn, alreadySorted) {
      var array1Index = 0;
      var array2Index = 0;
    
      const merged = [];
    
      if (!alreadySorted) {
        array1.sort(compareFn);
        array2.sort(compareFn);
      }
    
      while (array1Index < array1.length && array2Index < array2.length) {
        var comparedValue = compareFn(array1[array1Index], array2[array2Index]);
        if (comparedValue === 0) {
          merged.push(mergeFn(array1[array1Index], array2[array2Index]));
          array1Index++;
          array2Index++;
        } else if (comparedValue < 0) {
          merged.push(mergeFn(array1[array1Index]));
          array1Index++;
        } else {
          merged.push(mergeFn(array2[array2Index]));
          array2Index++;
        }
      }
      while (array1Index < array1.length) {
        merged.push(mergeFn(array1[array1Index]));
        array1Index++;
      }
      while (array2Index < array2.length) {
        merged.push(mergeFn(array2[array2Index]));
        array2Index++;
      }
      return merged;
    }
    
    
    const array1 = [{
        "id": 10,
        isArray1: true
      },
      {
        "id": 11,
        isArray1: true
      },
      {
        "id": 12,
        isArray1: true
      },
    ];
    const array2 = [{
        "id": 8,
        isArray2: true
      },
      {
        "id": 11,
        isArray2: true
      },
      {
        "id": 15,
        isArray2: true
      },
    ];
    
    const result = mergeObjectsBasedOnKey(array1, array2, function(a, b) {
      return a.id - b.id;
    }, function(a, b) {
      if (b) {
        return _.merge(a, b);
      }
      return _.merge(a, {
        isArray1: true,
        isArray2: true
      });
    });
    
    console.log(result);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

    And the results would be:

    [ { id: 8, isArray2: true, isArray1: true },
      { id: 10, isArray1: true, isArray2: true },
      { id: 11, isArray1: true, isArray2: true },
      { id: 12, isArray1: true, isArray2: true },
      { id: 15, isArray2: true, isArray1: true } ]
    
    0 讨论(0)
提交回复
热议问题