ho scritto un rapido soluzione non-così-rapido
. L'unico problema che si potrebbe prendere in considerazione è se una proprietà da un oggetto nel secondo array dovrebbe ignorare la stessa proprietà, se presente, per il secondo oggetto è essere paragonato a.
Soluzione 1
Questa soluzione è di complessità O(n²)
. La soluzione 2 è molto più veloce; questa soluzione è solo per coloro che non vogliono essere Sanic the Hedgehog veloce.
JavaScript
var mergeByKey = function (arr1, arr2, key) {
// key is the key that the function merges based on
arr1.forEach(function (d, i) {
var prop = d[key];
// since keys are unique, compare based on this key's value
arr2.forEach(function (f) {
if (prop == f[key]) { // if true, the objects share keys
for (var x in f) { // loop through each key in the 2nd object
if (!(x in d)) // if the key is not in the 1st object
arr1[i][x] = f[x]; // add it to the first object
// this is the part you might want to change for matching properties
// which object overrides the other?
}
}
})
})
return arr1;
}
banco di prova
var arr = [ {'key':1, 'property1': 'x'},
{'key':2, 'property1': 'y'} ],
arr2= [ {'key':2, 'property2': 'a'},
{'key':1, 'property2': 'b'} ];
console.log(mergeByKey(arr, arr2, "key"));
Risultati
/* returns:
Object
key: 1
property1: "x"
property2: "b"
__proto__: Object
and
Object
key: 2
property1: "y"
property2: "a"
__proto__: Object
*/
Soluzione 2
Come Vivin Paliath sottolineato nei commenti qui sotto, la mia prima soluzione era di O(n²)
complessità (leggi: cattivo). La sua risposta è molto buono e fornisce una soluzione con una complessità di O(m + n)
, dove m
è la dimensione della prima matrice e n
della seconda matrice. In altre parole, di complessità O(2n)
.
Tuttavia, la sua soluzione non affronta gli oggetti all'interno di oggetti. Per risolvere questo problema, ho usato la ricorsione lettura: il diavolo, proprio come O(n²)
.
JavaScript
var mergeByKey = function (arr1, arr2, key) {
var holder = [],
storedKeys = {},
i = 0; j = 0; l1 = arr1.length, l2 = arr2.length;
var merge = function (obj, ref) {
for (var x in obj) {
if (!(x in ref || x instanceof Object)) {
ref[x] = obj[x];
} else {
merge(obj[x], ref[x]);
}
}
storedKeys[obj.key] = ref;
}
for (; i < l1; i++) {
merge(arr1[i], storedKeys[arr1[i].key] || {});
}
for (; j < l2; j++) {
merge(arr2[j], storedKeys[arr2[j].key] || {});
}
delete storedKeys[undefined];
for (var obj in storedKeys)
holder.push(storedKeys[obj]);
return holder;
}
banco di prova
var arr1 = [
{
"key" : 1,
"prop1" : "x",
"test" : {
"one": 1,
"test2": {
"maybe" : false,
"test3": { "nothing" : true }
}
}
},
{
"key" : 2,
"prop1": "y",
"test" : { "one": 1 }
}],
arr2 = [
{
"key" : 1,
"prop2" : "y",
"test" : { "two" : 2 }
},
{
"key" : 2,
"prop2" : "z",
"test" : { "two": 2 }
}];
console.log(mergeByKey(arr1, arr2, "key"));
Risultati
/*
Object
key: 1
prop1: "x"
prop2: "y"
test: Object
one: 1
test2: Object
maybe: false
test3: Object
nothing: true
__proto__: Object
__proto__: Object
two: 2
__proto__: Object
__proto__: Object
Object
key: 2
prop1: "y"
prop2: "z"
test: Object
one: 1
two: 2
__proto__: Object
__proto__: Object
*/
Questa correttamente m adatta gli oggetti, insieme a tutti gli oggetti figli. Questa soluzione presuppone che gli oggetti con corrispondenza di keys
abbiano le stesse gerarchie.Inoltre, non gestisce la fusione di due array.
Stai identificando in modo univoco gli oggetti con 'chiave'? –
sì, le chiavi sono univoche – user3409889