Another approach that utilizes sort()
and reduce()
.
JSFiddle example.
Code:
/* Merges two objects into one. You might add some custom logic here,
if you need to handle some more complex merges, i.e. if the same
key appears in merged objects in both arrays */
var merge = function(o1, o2) {
var result = {};
for (var a in o1) { result[a] = o1[a]; }
for (var a in o2) { result[a] = o2[a]; }
return result;
}
/* Returns 0 if two objects are equal, -1 if first one is 'lower',
and 1 if it's 'larger'. It's used to sort the arrays. Objects are
compared using iso3 and year properties only. */
var compareByIsoAndYear = function (o1, o2) {
if (o1.iso3 === o2.iso3 && o1.year === o2.year) return 0
else if (o1.year > o2.year) return 1
else if (o1.year < o2.year) return -1
else if (o1.iso3 > o2.iso3) return 1;
}
/* Used in reduce */
var mergeTwoObjects = function(initial, current) {
if (initial.length > 0) {
var last = initial[initial.length-1];
if (compareByIsoAndYear(last, current) === 0) {
initial[initial.length-1] = merge(last, current);
return initial;
}
}
initial.push(current);
return initial;
}
/* Take both arrays and concatenate them into one. Then sort them,
to make sure that objects with the same year and iso3 would appear
next to each other, and then merge them if needed */
var result = array1.concat(array2)
.sort(compareByIsoAndYear)
.reduce(mergeTwoObjects, []);
Result:
[{
"indicator_id": 23806, /* Found in array2 only, not merged */
"footnote_id": 15711,
"iso3": "AFG",
"year": 2013
}, {
"id": 138806, /* This one has been merged */
"iso3": "ALB",
"country": "Albania",
"year": 2013,
"value": 0.6341109715,
"indicator_id": 123406,
"footnote_id": 15711
}, {
"indicator_id": 101606, /* Found in array2 only, not merged */
"footnote_id": 48911,
"iso3": "DZA",
"year": 2013
}, {
"id": 24006, /* This one has been merged */
"iso3": "AFG",
"country": "Afghanistan",
"year": 2014,
"value": 29.78,
"indicator_id": 21806,
"footnote_id": 64811
}, {
"id": 44206, /* Found in array1 only, not merged */
"iso3": "DZA",
"country": "Algeria",
"year": 2014,
"value": 39.928947
}]