3287 Stimmen

Wie kann ich die Eigenschaften von zwei JavaScript-Objekten dynamisch zusammenführen?

Ich muss in der Lage sein, zwei (sehr einfache) JavaScript-Objekte zur Laufzeit zu verschmelzen. Zum Beispiel würde ich gerne:

var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog' }

obj1.merge(obj2);

//obj1 now has three properties: food, car, and animal

Gibt es eine eingebaute Möglichkeit, dies zu tun? Ich brauche keine Rekursion, und ich muss nicht Funktionen zusammenführen, nur Methoden auf flache Objekte.

0 Stimmen

Es ist erwähnenswert diese Antwort auf eine ähnliche Frage , die zeigt, wie man "eine Ebene tiefer" zusammenführt. Das heißt, es werden Werte mit doppelten Schlüsseln zusammengeführt (anstatt den ersten Wert mit dem zweiten zu überschreiben), aber es wird nicht weiter rekursiert als das. IMHO ist es ein guter, sauberer Code für diese Aufgabe.

0 Stimmen

Übrigens führen die ersten paar Antworten eine "oberflächliche" Zusammenführung durch: Wenn derselbe Schlüssel sowohl in obj1 als auch in obj2 vorhanden ist, wird der Wert in obj2 beibehalten, der Wert in obj1 wird gelöscht. Wenn z.B. das Beispiel der Frage var obj2 = { animal: 'dog', food: 'bone' }; wäre die Verschmelzung { food: 'bone', car: 'ford', animal: 'dog' } . Wenn Sie mit "verschachtelten Daten" arbeiten und eine "tiefe Zusammenführung" wünschen, suchen Sie nach Antworten, die "tiefe Zusammenführung" oder "Rekursion" erwähnen. Wenn Sie Werte haben, die arrays verwenden Sie dann die Option "arrayMerge" von github "TehShrike/deepmerge", wie erwähnt aquí .

37voto

appsmatics Punkte 629

Die folgenden zwei sind wahrscheinlich ein guter Ausgangspunkt. lodash hat auch eine Anpassungsfunktion für diese speziellen Bedürfnisse!

_.extend ( http://underscorejs.org/#extend )
_.merge ( https://lodash.com/docs#merge )

34voto

Paul Spaulding Punkte 961

Hier ist mein Versuch, der

  1. Unterstützt Deep Merge
  2. Mutiert nicht die Argumente
  3. Nimmt eine beliebige Anzahl von Argumenten entgegen
  4. Erweitert den Objektprototyp nicht
  5. Hängt nicht von einer anderen Bibliothek ab ( jQuery , MooTools , Underscore.js , usw.)
  6. Enthält Prüfung auf hasOwnProperty
  7. Ist kurz :)

    /*
        Recursively merge properties and return new object
        obj1 <- obj2 [ <- ... ]
    */
    function merge () {
        var dst = {}
            ,src
            ,p
            ,args = [].splice.call(arguments, 0)
        ;
    
        while (args.length > 0) {
            src = args.splice(0, 1)[0];
            if (toString.call(src) == '[object Object]') {
                for (p in src) {
                    if (src.hasOwnProperty(p)) {
                        if (toString.call(src[p]) == '[object Object]') {
                            dst[p] = merge(dst[p] || {}, src[p]);
                        } else {
                            dst[p] = src[p];
                        }
                    }
                }
            }
        }
    
       return dst;
    }

Ejemplo:

a = {
    "p1": "p1a",
    "p2": [
        "a",
        "b",
        "c"
    ],
    "p3": true,
    "p5": null,
    "p6": {
        "p61": "p61a",
        "p62": "p62a",
        "p63": [
            "aa",
            "bb",
            "cc"
        ],
        "p64": {
            "p641": "p641a"
        }
    }
};

b = {
    "p1": "p1b",
    "p2": [
        "d",
        "e",
        "f"
    ],
    "p3": false,
    "p4": true,
    "p6": {
        "p61": "p61b",
        "p64": {
            "p642": "p642b"
        }
    }
};

c = {
    "p1": "p1c",
    "p3": null,
    "p6": {
        "p62": "p62c",
        "p64": {
            "p643": "p641c"
        }
    }
};

d = merge(a, b, c);

/*
    d = {
        "p1": "p1c",
        "p2": [
            "d",
            "e",
            "f"
        ],
        "p3": null,
        "p5": null,
        "p6": {
            "p61": "p61b",
            "p62": "p62c",
            "p63": [
                "aa",
                "bb",
                "cc"
            ],
            "p64": {
                "p641": "p641a",
                "p642": "p642b",
                "p643": "p641c"
            }
        },
        "p4": true
    };
*/

31voto

Andreas Linden Punkte 12235

Übrigens, was Sie alle tun, ist das Überschreiben von Eigenschaften, nicht das Zusammenführen...

Auf diese Weise wird der Bereich der JavaScript-Objekte wirklich zusammengeführt: Nur Schlüssel im to Objekte, die nicht selbst Objekte sind, werden überschrieben durch from . Alles andere wird wirklich zusammengeführt . Natürlich können Sie dieses Verhalten so ändern, dass nichts Vorhandenes überschrieben wird, z. B. nur wenn to[n] is undefined , usw...:

var realMerge = function (to, from) {

    for (n in from) {

        if (typeof to[n] != 'object') {
            to[n] = from[n];
        } else if (typeof from[n] == 'object') {
            to[n] = realMerge(to[n], from[n]);
        }
    }
    return to;
};

Verwendung:

var merged = realMerge(obj1, obj2);

20voto

Algy Punkte 93

Für nicht allzu komplizierte Objekte können Sie Folgendes verwenden JSON :

var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog', car: 'chevy'}
var objMerge;

objMerge = JSON.stringify(obj1) + JSON.stringify(obj2);

// {"food": "pizza","car":"ford"}{"animal":"dog","car":"chevy"}

objMerge = objMerge.replace(/\}\{/, ","); //  \_ replace with comma for valid JSON

objMerge = JSON.parse(objMerge); // { food: 'pizza', animal: 'dog', car: 'chevy'}
// Of same keys in both objects, the last object's value is retained_/

Beachten Sie, dass in diesem Beispiel "}{" darf nicht vorkommen innerhalb einer Zeichenkette!

20voto

Reza Roshan Punkte 150

Object.assign()

ECMAScript 2015 (ES6)

Dies ist eine neue Technologie, die Teil des ECMAScript 2015 (ES6) Standards ist. Die Spezifikation dieser Technologie wurde fertiggestellt, aber in der Kompatibilitätstabelle finden Sie Informationen zur Verwendung und zum Implementierungsstatus in verschiedenen Browsern.

Die Methode Object.assign() wird verwendet, um die Werte aller aufzählbaren eigenen Eigenschaften von einem oder mehreren Quellobjekten in ein Zielobjekt zu kopieren. Sie gibt das Zielobjekt zurück.

var o1 = { a: 1 };
var o2 = { b: 2 };
var o3 = { c: 3 };

var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1);  // { a: 1, b: 2, c: 3 }, target object itself is changed.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X