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.

1

3 Answers 3

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>

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.