2

I have an array of objects like

var data = {"part1": [{"id": 1, "a": 50},{"id": 2, "a": 55},{"id": 4, "a": 100}],
            "part2":[{"id": 1, "b": 40}, {"id": 3, "b": 45}, {"id": 4, "b": 110}]
           };

I need to merge part1 and part2 (preferably with lodash) to get

var result = [
              {"id": 1, "a": 50, "b": 40},
              {"id": 2, "a": 55},
              {"id": 3, "b": 45},
              {"id": 4, "a": 100, "b": 110}
             ];

Note: I need to merge based on id, if it exists, else copy the other objects as they are. The size and order of part1 and part2 will vary and it is possible for them to not have any common id as well.

doubleA
  • 21
  • 1
  • 3
  • did you try reading the documentation, and googling it, Because I found this right away . http://stackoverflow.com/questions/19480008/javascript-merging-objects-by-id – Abdul Shaikh Apr 24 '17 at 06:08

3 Answers3

4

You can use lodash's _.groupBy() and _.merge() to combine multiple objects with the same property (id in this case) into a single one:

var data = {"part1": [{"id": 1, "a": 50},{"id": 2, "a": 55},{"id": 4, "a": 100}], "part2":[{"id": 1, "b": 40}, {"id": 3, "b": 45}, {"id": 4, "b": 110}] };

var result = _(data)
  .values() // extract the arrays from the object
  .flatten() // flatten them to a single array
  .groupBy('id') // group them by the ids
  .map(function(values) { // map the groups
    return _.merge.apply(_, [{}].concat(values)); // merge all elements in the group. I'm using apply to merge the array of object, and add an empty object, so the original objects won't be mutated
  })
  .value(); // finish the chain

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
0

Try this

var data = {"part1": [{"id": 1, "a": 50}, {"id": 2, "a": 55}, {"id": 4, "a": 100}],
    "part2": [{"id": 1, "b": 40}, {"id": 3, "b": 45}, {"id": 4, "b": 110}]
};

var finalArr = [];

// Collecting all items with common ids
for (var i = 0; i < data.part1.length; i++) {
    var tempi = data.part1[i];
    for (var j = 0; j < data.part2.length; j++) {
        var tempj = data.part2[j];
        if (tempi.id == tempj.id) {
            tempi.b = tempj.b;
            finalArr.push(tempi);
        }
    }
}

// collecting the remaining items
for (var k = 0; k < data.part2.length; k++) {
    var tempk = data.part2[k];
    var itemFound = false;
    for (var l = 0; l < finalArr.length; l++) {
        var templ = finalArr[l];
        if (tempk.id == templ.id) {
            itemFound = true;
        }
    }
    if (!itemFound) {
        finalArr.push(tempk);
    }
}

console.log(finalArr.toString());

//finalArr is the result you want
Sarin Jacob Sunny
  • 2,138
  • 3
  • 29
  • 61
0

You could use an dynamic approach for all keys of the given object and merge all properties to the object with the same id. Later sort the array.

var data = { part1: [{ id: 1, a: 50 }, { id: 2, a: 55 }, { id: 4, a: 100 }], part2: [{ id: 1, b: 40 }, { id: 3, b: 45 }, { id: 4, b: 110 }] },
    result = Object.keys(data).reduce(function (hash) {
        return function (r, k) {
            data[k].forEach(function (o) {
                if (!hash[o.id]) {
                    hash[o.id] = {};
                    r.push(hash[o.id]);
                }
                Object.keys(o).forEach(function (l) {
                    hash[o.id][l] = o[l];
                });
            });
            return r;
        };
    }(Object.create(null)), []);

result.sort(function (a, b) { return a.id - b.id; });
  
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392