1

I try to merge 2 array of objects using Object assign. I know I can do this with map by comparing their ids, but somehow didn't worked in object.assign?

const ageArr = [{
  "id": 1,
  "age_range": "0 - 10 Years old",
  "value": 1
}, {
  "id": 2,
  "age_range": "11 - 20 Years old",
  "value": 1
}, {
  "id": 3,
  "age_range": "21 - 30 Years old",
  "value": 78
}]

const colorArr = [{
  "id": 1,
  "color": "#333"
}, {
  "id": 2,
  "color": "#666"
}, {
  "id": 3,
  "color": "#999"
}]

const mergedArr = Object.assign({}, ageArr, colorArr)
console.log(mergedArr)

https://jsfiddle.net/u6L2ceux

7
  • 1
    are the arrays ordered, that the id is always corresponding to the object with the same index? Commented Aug 11, 2017 at 8:41
  • @NinaScholz it doesn't matter right? as long as the ids of 2 arrays matched Commented Aug 11, 2017 at 8:43
  • Object assign does different thing, it makes prototype inheritance of Objects, not arrays. Commented Aug 11, 2017 at 8:43
  • @zb' Object.assign has nothing to do with inheritance Commented Aug 11, 2017 at 8:49
  • 1
    @zb' I think you were confusing that with Object.create. And no, your fiddle shows that Object.assign returns its first argument - Parent === Child. Commented Aug 11, 2017 at 9:01

4 Answers 4

2

You could use Map and two loops.

const
    ageArr = [{ id: 1, age_range: "0 - 10 Years old", value: 1 }, { id: 2, age_range: "11 - 20 Years old", value: 1 }, { id: 3, age_range: "21 - 30 Years old", value: 78 }],
    colorArr = [{ id: 1, color: "#333" }, { id: 2, color: "#666" }, { id: 3, color: "#999" }],
    map = new Map(ageArr.map(o => [o.id, o])),
    mergedArr = colorArr.map(o => Object.assign({}, o, map.get(o.id) || {}));

console.log(mergedArr);
.as-console-wrapper { max-height: 100% !important; top: 0; }

For not same array length, you could collect first all objects with the same id in the map and render then result.

var ageArr = [{ id: 1, age_range: "0 - 10 Years old", value: 1 }, { id: 2, age_range: "11 - 20 Years old", value: 1 }],
    colorArr = [{ id: 2, color: "#666" }, { id: 3, color: "#999" }],
    map = new Map,
    result;

[ageArr, colorArr].forEach(a =>
    a.forEach(o => map.set(o.id, Object.assign(map.get(o.id) || {}, o)))
);
result = [...map.values()];

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

5 Comments

hmm this is too complicated, do you have a more simple solution?
what means simple? a solution with more lines and an object for the reference to the same id?
jsfiddle.net/r8jdqe1k this is simple, but it might break if the ageArr has 4 items.
using find is a solution as well, but on large arrays it could take more time.
but how to solve the error if the item is not the same length?
1

You can do this using map method in combination with Object.assign

const ageArr = [{
  "id": 1,
  "age_range": "0 - 10 Years old",
  "value": 1
}, {
  "id": 2,
  "age_range": "11 - 20 Years old",
  "value": 1
}, {
  "id": 3,
  "age_range": "21 - 30 Years old",
  "value": 78
}]

const colorArr = [{
  "id": 1,
  "color": "#333"
}, {
  "id": 2,
  "color": "#666"
}, {
  "id": 3,
  "color": "#999"
}]

const mergedArr = colorArr.map((item,i)=>Object.assign({},item,ageArr[i]));
console.log(mergedArr)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

2 Comments

I know this but avoid it coz we don't use jquery.
@JessieAnderson, have a look now. I try map with Object.assign..solution in one line.
0

Object.assign does not recursively merge objects. It just does shallow copies of object properties. In your case, it copies the values of the properties 0, 1 and 2 from colorArr to the empty object.

Instead use a loop over your arrays and Object.assign to merge the individual items:

const mergedArr = [];
for (let i=0; i<Math.min(ageArr.length, colorArr.length); i++) {
    assert(ageArr[i].id === colorArr[i].id); // if they don't match you need to do a lookup
    mergedArr[i] = Object.assign({}, ageArr[i], colorArr[i]);
}

Comments

-2

In case you just want to add both arrays into one you could try this:

const ageArr = [{
  "id": 1,
  "age_range": "0 - 10 Years old",
  "value": 1
}, {
  "id": 2,
  "age_range": "11 - 20 Years old",
  "value": 1
}, {
  "id": 3,
  "age_range": "21 - 30 Years old",
  "value": 78
}]

const colorArr = [{
  "id": 1,
  "color": "#333"
}, {
  "id": 2,
  "color": "#666"
}, {
  "id": 3,
  "color": "#999"
}]

const mergedArr = ageArr.concat(colorArr)
console.log(mergedArr)

Remember that the concat function does return a new array and doesnt make any changes to any other array. Meaning colorArr and ageArr are unchanged after the concat() call.

Take a look at the documentation: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/concat

1 Comment

this is not what I want.

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.