Looks like you already accepted an answer but I'll post mine as well. It has the following advantages:
- It preserves the original level objects by creating shallow copies of them.
- It intersects objects with the same key and doesn't add duplicate values.
Here is the code:
var levels = [
{
country_id: 356,
country_name: "aaa",
level0: "bbbb",
level1: "cccc",
level2: "dddd",
level3: "eeee",
level4: "fffff"
},
{
country_id: 356,
country_name: "aaaa",
level0: "bbbb",
level1: "cccc",
level2: "dddd",
level3: "eeee",
level4: "gggg"
},
{
country_id: 356,
country_name: "aaaa",
level0: "bbbb",
level1: "cccd",
level2: "dddd",
level3: "eeee",
level4: "gggg"
},
{
country_id: 354,
country_name: "aaaa",
level0: "bbbb",
level1: "cccc",
level2: "dddd",
level3: "eeee",
level4: "gggg"
}
];
var mergedLevels = {};
function shallowCopyWithoutId(object) {
var o = {},
i;
for (i in object) {
if (object.hasOwnProperty(i) && i !== 'country_id') {
o[i] = object[i];
}
}
return o;
}
function merge(o1, o2) {
var i;
for (i in o1) {
if (o1.hasOwnProperty(i) && o2.hasOwnProperty(i)) {
if (o1[i] instanceof Array) {
if (o1[i].indexOf(o2[i]) === -1) o1[i].push(o2[i]);
} else if (o1[i] !== o2[i]) {
o1[i] = [o1[i], o2[i]];
}
}
}
}
var i, level;
for (i = 0; i < levels.length; i++) {
level = levels[i];
if (!mergedLevels.hasOwnProperty(level.country_id)) {
mergedLevels[level.country_id] = shallowCopyWithoutId(level);
} else {
merge(mergedLevels[level.country_id], level);
}
}
console.log(mergedLevels);
Output:
{ '354':
{ country_name: 'aaaa',
level0: 'bbbb',
level1: 'cccc',
level2: 'dddd',
level3: 'eeee',
level4: 'gggg' },
'356':
{ country_name: [ 'aaa', 'aaaa' ],
level0: 'bbbb',
level1: [ 'cccc', 'cccd' ],
level2: 'dddd',
level3: 'eeee',
level4: [ 'fffff', 'gggg' ] } }