Jessie Anderson
Jessie Anderson

Reputation: 319

Object assign to merge 2 array of object and keep self property

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

Upvotes: 1

Views: 5887

Answers (4)

Nina Scholz
Nina Scholz

Reputation: 386730

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

Upvotes: 2

Mihai Alexandru-Ionut
Mihai Alexandru-Ionut

Reputation: 48407

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>

Upvotes: 1

Bergi
Bergi

Reputation: 665030

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

Upvotes: 0

Kevin Vujic
Kevin Vujic

Reputation: 7

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

Upvotes: -2

Related Questions