Was ist die beste / Standardmethode zum Zusammenführen von zwei assoziativen Arrays in JavaScript? Tut jeder das nur, indem er seine eigene forSchleife rollt ?
Was ist die beste / Standardmethode zum Zusammenführen von zwei assoziativen Arrays in JavaScript? Tut jeder das nur, indem er seine eigene forSchleife rollt ?
Antworten:
mit jquery können Sie anrufen $.extend
var obj1 = {a: 1, b: 2};
var obj2 = {a: 4, c: 110};
var obj3 = $.extend(obj1, obj2);
obj1 == obj3 == {a: 4, b: 2, c: 110} // Pseudo JS
(Assoc. Arrays sind Objekte in js)
Schauen Sie hier: http://api.jquery.com/jQuery.extend/
edit: Wie von rymo vorgeschlagen, ist es besser, es so zu machen:
obj3 = $.extend({}, obj1, obj2);
obj3 == {a: 4, b: 2, c: 110}
Wie hier bleiben obj1 (und obj2) unverändert.
edit2: Im Jahr 2018 ist der Weg dazu Object.assign:
var obj3 = Object.assign({}, obj1, obj2);
obj3 === {a: 4, b: 2, c: 110} // Pseudo JS
Wenn Sie mit ES6 arbeiten, kann dies mit dem Spread Operator erreicht werden :
const obj3 = { ...obj1, ...obj2 };
obj1$.extend({}, obj1, obj2)
Object.assign(), die nicht auf JQuery basiert , wenn Sie die Bibliothek nicht bereits verwenden.
Jetzt im Jahr 2016 würde ich sagen, dass der beste / Standardweg Object.assign ()
Pure Javascript ist. Es wird keine jQuery benötigt.
obj1 = {a: 1, b: 2};
obj2 = {a: 4, c: 110};
obj3 = Object.assign({},obj1, obj2); // Object {a: 4, b: 2, c: 110}
Weitere Informationen, Beispiele und Polyfill finden Sie hier:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
So macht es Prototype:
Object.extend = function(destination, source) {
for (var property in source) {
if (source.hasOwnProperty(property)) {
destination[property] = source[property];
}
}
return destination;
};
genannt als zum Beispiel:
var arr1 = { robert: "bobby", john: "jack" };
var arr2 = { elizabeth: "liz", jennifer: "jen" };
var shortnames = Object.extend(arr1,arr2);
EDIT : hinzugefügt hasOwnProperty () überprüfen , wie richtig durch bucabay in den Kommentaren darauf hingewiesen ,
Halte es einfach...
function mergeArray(array1,array2) {
for(item in array1) {
array2[item] = array1[item];
}
return array2;
}
arrau1.prototype
hasOwnPropertyScheck. Das Verweisen auf die Objekte als Arrays ist ebenfalls irreführend (sie sind Objekte). Die Arg-Namen sollten vermitteln, dass Array2 mutiert ist, oder ein neues Objekt sollte zurückgegeben werden. Ich würde die Antwort bearbeiten, aber tatsächlich würde es fast genau Jonathan Finglands bearbeitete Antwort werden, die bereits korrigiert wurde.
Unterstrich hat auch eine Erweiterungsmethode:
Kopieren Sie alle Eigenschaften in den Quellobjekten in das Zielobjekt. Es ist in der richtigen Reihenfolge, sodass die letzte Quelle gleichnamige Eigenschaften in vorherigen Argumenten überschreibt.
_.extend(destination, *sources)
_.extend({name : 'moe'}, {age : 50});
=> {name : 'moe', age : 50}
Im Dojo wäre die "Zusammenführung" der 2 Objekte / Arrays lang.mixin(destination, source)- Sie können auch mehrere Quellen zu einem Ziel mischen usw. - Einzelheiten finden Sie in der Referenz der Mixin-Funktion .
Möchten Sie eine Eigenschaft überschreiben, wenn die Namen identisch sind, die Werte jedoch nicht?
Und möchten Sie eines der Originalobjekte dauerhaft ändern?
oder möchten Sie ein neues zusammengeführtes Objekt zurückgeben?
function mergedObject(obj1, obj2, force){
for(var p in obj1) this[p]= obj1[p];
for(var p in obj2){
if(obj2.hasOwnProperty(p)){
if(force || this[p]=== undefined) this[p]= obj2[p];
else{
n= 2;
while(this[p+n]!== undefined)++n;
this[p+n]= obj2[p];
}
}
}
}
function extend(objects) {
var args
, first = Array.prototype.slice.call(arguments, 0, 1)[0]
, second;
if (arguments.length > 1) {
second = Array.prototype.splice.call(arguments, 1, 1)[0];
for (var key in second) {
first[key] = second[key];
}
args = Array.prototype.slice.call(arguments, 0);
return extend.apply(this, args);
}
return first;
}
...
var briansDirections = {
step1: 'Remove pastry from wrapper.',
step2: 'Place pastry toaster.',
step3: 'Remove pastry from toaster and enjoy.',
};
extend(briansDirections, { step1: 'Toast Poptarts' }, { step2: 'Go ahead, toast \'em' }, { step3: 'Hey, are you sill reading this???' });
...
Dies erweitert einfach einen Teil der Objekte rekursiv. Beachten Sie außerdem, dass diese rekursive Funktion TCO ( Tail-Call Optimized ) ist, da ihre Rückgabe der letzte Aufruf an sich selbst ist.
Darüber hinaus möchten Sie möglicherweise gezielte Eigenschaften . In diesem Fall können Sie Objekte kondensieren auf der Basis id, quantityoder eine andere Eigenschaft. Dieser Ansatz könnte ein kleines Buch darüber schreiben und erfordert eine Gegenüberstellung von Objekten und kann sehr komplex werden. Ich habe dafür eine kleine Bibliothek geschrieben, die auf Anfrage erhältlich ist.
Hoffe das hilft!
Im Jahr 2019 haben Sie 2 gute Möglichkeiten:
Objektzuweisung [ doc ]
const result = Object.assign({}, baseObject, updatingObject);
Objektverbreitung [ doc ]
const result = { ...baseObject, ...updatingObject};
Der erste ist tendenziell sicherer, standardisierter und polyvalenter. Ein gutes Für und Wider hier
Yahoo UI (YUI) hat auch eine Hilfsfunktion dafür:
http://developer.yahoo.com/yui/examples/yahoo/yahoo_merge.html
YAHOO.namespace('example');
YAHOO.example.set1 = { foo : "foo" };
YAHOO.example.set2 = { foo : "BAR", bar : "bar" };
YAHOO.example.set3 = { foo : "FOO", baz : "BAZ" };
var Ye = YAHOO.example;
var merged = YAHOO.lang.merge(Ye.set1, Ye.set2, Ye.set3);
jquery hat einen Booleschen Wert für Deep Copy. Sie könnten so etwas tun:
MergeRecursive = function(arr1, arr2){
$.extend(true, arr1, arr2);
return arr1;
};
Sie können diese Funktion auch bearbeiten, um das Zusammenführen von n-Arrays zu unterstützen.
ArrayMergeRecursive = function(){
if(arguments.length < 2){
throw new Error("ArrayMergeRecursive: Please enter two or more objects to merge!");
}
var arr1=arguments[0];
for(var i=0; i<=arguments.length; i++ ){
$.extend(true, arr1, arguments[i]);
}
return arr1;
};
Jetzt können Sie es also tun
var arr1 = {'color': {'mycolor': 'red'}, 3: 5},
arr2 = {4: 10, 'color': {'favorite': 'green', 0: 'blue'}},
arr3 = ['Peter','Jhon','Demosthenes'],
results = ArrayMergeRecursive(arr1, arr2, arr3); // (arr1, arr2 ... arrN)
console.log("Result is:", results);
Ich brauchte eine tiefe Objektverschmelzung. Alle anderen Antworten haben mir also nicht sehr geholfen. _.extend und jQuery.extend funktionieren gut, es sei denn, Sie haben ein rekursives Array wie ich. Aber es ist nicht so schlimm, Sie können es in fünf Minuten programmieren:
var deep_merge = function (arr1, arr2) {
jQuery.each(arr2, function (index, element) {
if (typeof arr1[index] === "object" && typeof element === "object") {
arr1[index] = deep_merge(arr1[index], element);
} else if (typeof arr1[index] === "array" && typeof element === "array") {
arr1[index] = arr1[index].concat(element);
} else {
arr1[index] = element;
}
});
return arr1;
}
Um Arrays in jQuery zusammenzuführen, was ist mit $ .merge?
var merged = $.merge([{id:3, value:'foo3'}], [{id:1, value:'foo1'}, {id:2, value:'foo2'}]);
merged[0].id == 3;
merged[0].value == 'foo3';
merged[1].id == 1;
merged[1].value == 'foo1';
merged[2].id == 2;
merged[2].value == 'foo2';
var addProps = function (original, props) {
if(!props) {
return original;
}
if (Array.isArray(original)) {
original.map(function (e) {
return addProps(e, props)
});
return original;
}
if (!original) {
original = {};
}
for (var property in props) {
if (props.hasOwnProperty(property)) {
original[property] = props[property];
}
}
return original;
};
Tests
console.log(addProps([{a: 2}, {z: 'ciao'}], {timestamp: 13}));
console.log(addProps({single: true}, {timestamp: 13}));
console.log(addProps({}, {timestamp: 13}));
console.log(addProps(null, {timestamp: 13}));
[ { a: 2, timestamp: 13 }, { z: 'ciao', timestamp: 13 } ]
{ single: true, timestamp: 13 }
{ timestamp: 13 }
{ timestamp: 13 }
Object.getOwnPropertyNames is not a functiondie App wird abstürzen.