Kombinieren oder führen Sie JSON auf node.js ohne jQuery zusammen

77

Ich habe mehrere JSONwie diese

var object1 = {name: "John"};
var object2 = {location: "San Jose"};

Sie nisten nicht oder so etwas. Nur grundsätzlich verschiedene Bereiche. Ich brauche sie in einem einzigen zu kombinieren JSONin node.js wie folgt aus :

{name: "John", location: "San Jose"}

Ich kann jQuery gut verwenden. Hier ist ein funktionierendes Beispiel im Browser:

http://jsfiddle.net/qhoc/agp54/

Wenn ich dies jedoch in node.js mache, möchte ich jQuery nicht laden (was etwas überstrapaziert ist, und die jQuery von node.js funktioniert auf meinem Windows- Computer nicht).

Gibt es also eine einfache Möglichkeit, ähnliche Dinge wie $.extend()ohne jQuery zu tun ?

HP.
quelle
2
Wenn Sie verschiedene Dinge wie diese tun, sollten Sie Underscore verwenden , das als Knotenmodul verfügbar ist .
James Allardice
1
npm install extend, Port of jQuery.extend für Node.js .
Joel Purra
FYI Object.assign macht dies, wird aber derzeit leider nicht unterstützt. Hoffentlich bald! developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Rene Wooller
1
Das ist kein JSON, Sie erstellen nur Standard-JS-Objekte in Literalschreibweise. (ZB in JSON müssen Schlüssel Zeichenfolgen sein). Und wenn Sie diese Objekte "kombinieren", hat dies nichts mit JSON zu tun.
UpTheCreek

Antworten:

42

Eine normale Schleife?

function extend(target) {
    var sources = [].slice.call(arguments, 1);
    sources.forEach(function (source) {
        for (var prop in source) {
            target[prop] = source[prop];
        }
    });
    return target;
}

var object3 = extend({}, object1, object2);

Das ist ein grundlegender Ausgangspunkt. Möglicherweise möchten Sie beispielsweise eine hasOwnPropertyPrüfung hinzufügen oder eine Logik hinzufügen, um den Fall zu behandeln, in dem mehrere Quellobjekte eine Eigenschaft mit demselben Bezeichner haben.

Hier ist ein Arbeitsbeispiel .

Randnotiz : Was Sie als "JSON" bezeichnen, sind eigentlich normale JavaScript-Objekte. JSON ist einfach ein Textformat, das eine gewisse Syntax mit JavaScript teilt.

James Allardice
quelle
Ich benutze diese Funktion, um zwei JSON zusammenzuführen. Dem resultierenden json wird jedoch '0' vorangestellt. Beispiel 0: {kye: value}. Bitte helfen Sie mir, wie ich meine eigene Zeichenfolge anstelle von '0' voranstellen kann.
Saurabh Ghewari
7
Abgestimmt, weil dies einer der Fälle ist, in denen Personen, insbesondere Neulinge, zu getesteten Bibliotheken geleitet werden sollten.
Martin Wawrusch
122

Sie sollten " Object.assign () " verwenden.

Für einen so einfachen Anwendungsfall der flachen Verschmelzung muss das Rad nicht neu erfunden werden.

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

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

Sogar die Leute von Node.js sagen es so :

_extendwar nie für die Verwendung außerhalb interner NodeJS-Module vorgesehen. Die Community hat es trotzdem gefunden und benutzt. Es ist veraltet und sollte nicht in neuem Code verwendet werden. JavaScript kommt mit sehr ähnlichen integrierten Funktionen durch Object.assign.


Aktualisieren:

Sie können den Spread-Operator verwenden

Seit Version 8.6 ist es möglich, den Spread-Operator in Node.js nativ zu verwenden. Beispiel unten:

let o1 = { a: 1 };
let o2 = { b: 2 };
let obj = { ...o1, ...o2 }; // { a: 1, b: 2 }

Object.assign funktioniert aber immer noch.


PS1 : Wenn Sie tatsächlich an einer tiefen Zusammenführung interessiert sind (bei der interne Objektdaten - in beliebiger Tiefe - rekursiv zusammengeführt werden), können Sie Pakete wie deepmerge , assign -deep oder lodash.merge verwenden , die recht klein und einfach zu handhaben sind verwenden.

PS2 : Beachten Sie, dass Object.assign nicht mit 0.X-Versionen von Node.js funktioniert . Wenn Sie mit einer dieser Versionen arbeiten (sollten Sie jetzt wirklich nicht ), können Sie diese require("util")._extendwie im obigen Link Node.js gezeigt verwenden. Weitere Informationen finden Sie in der Antwort von tobymackenzie auf dieselbe Frage .

Ricardo Nolde
quelle
1
+1 Wenn Sie hierher kommen und nach einer nativen Browser- Alternative suchen , beachten Sie, dass dies eine ES6-Funktion ist und als solche noch nicht gut unterstützt wird .
Boaz
Wenn Sie dem Boaz- Kommentar Object.assignhinzufügen, finden Sie im obigen Mozilla-Link eine Polyfüllung, die in einem Browser einwandfrei funktioniert.
Ricardo Nolde
3
Nennen Sie es mit einem leeren ersten Argument, um zu vermeiden, dass Ihre Objekte versehentlich var obj = Object.assign({}, o1, o2, o3)
beschädigt
57

Wenn Sie die Knotenversion> = 4 verwenden, verwenden Sie Object.assign()(siehe Antwort von Ricardo Nolde ).

Wenn Sie Node 0.x verwenden, gibt es das eingebaute util._extend:

var extend = require('util')._extend
var o = extend({}, {name: "John"});
extend(o,  {location: "San Jose"});

Es wird keine tiefe Kopie erstellt und es werden nur zwei Argumente gleichzeitig zugelassen, es ist jedoch integriert. Ich habe dies bei einer Frage zum Klonen von Objekten im Knoten erwähnt: https://stackoverflow.com/a/15040626 .

Wenn Sie Bedenken hinsichtlich der Verwendung einer "privaten" Methode haben, können Sie diese jederzeit als Proxy verwenden:

// myutil.js
exports.extend = require('util')._extend;

und ersetzen Sie es durch Ihre eigene Implementierung, falls es jemals verschwindet. Dies ist (ungefähr) ihre Implementierung:

exports.extend = function(origin, add) {
    if (!add || (typeof add !== 'object' && add !== null)){
        return origin;
    }

    var keys = Object.keys(add);
    var i = keys.length;
    while(i--){
        origin[keys[i]] = add[keys[i]];
    }
    return origin;
};
Tobymackenzie
quelle
5
Der Unterstrich in _extend stellt eine private Methode dar, dh er ist nicht für die öffentliche Verwendung vorgesehen. Diese Methode ist nicht nur nicht dokumentiert, sondern die Implementierung kann sich bei jeder Überarbeitung ändern und sich auf Ihr Projekt auswirken.
aaaaaa
3
Wie @jimbojw in einem Kommentar zu der verknüpften Antwort erwähnte, sagt Isaacs: "Sie können weitermachen und verwenden util._extends()... Es wird nicht in absehbarer Zeit irgendwohin gehen . " In diesem Thread gibt es weitere Diskussionen. Wenn Sie sich Sorgen machen, lesen Sie durch und treffen Sie eine Entscheidung für Ihr Projekt.
Tobymackenzie
npm install util-verlängern
Maciej Krawczyk
1
Die _extend()Funktion wurde zugunsten von Object.Assign()- developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
brasskazoo
51

Unterstricheextend sind der einfachste und schnellste Weg, um dies zu erreichen, wie James kommentierte.

Hier ist ein Beispiel mit Unterstrich:

var _ = require('underscore'), // npm install underscore to install
  object1 = {name: "John"},
  object2 = {location: "San Jose"};

var target = _.extend(object1, object2);

Objekt 1 erhält die Eigenschaften von Objekt2 und wird zurückgegeben und dem Ziel zugewiesen. Sie können dies auch so tun, je nachdem, ob es Ihnen etwas ausmacht, Objekt1 zu ändern:

var target = {};
_.extend(target, object1, object2);
AndyD
quelle
1
Vielen Dank. Aber ich möchte auch den Unterstrich in node.js vermeiden, wenn ich kann.
HP.
1
Ich habe nur eine leichte node.js App mit nur Express und Mailjs. Ich möchte nur nicht mit anderen Bibliotheken laden, wenn ich nur eine Funktion verwende. Deine Idee ist trotzdem cool. Vielen Dank.
HP.
10
Achtung, die Ausdehnung des Unterstrichs befindet sich nur auf der ersten Ebene. Unterobjekte können nicht zusammengeführt werden.
Feugy
15

Verwenden Sie Zusammenführen .

$ npm install merge

Beispielcode:

var merge = require('merge'), // npm install -g merge
    original, cloned;

console.log(

    merge({ one: 'hello' }, { two: 'world' })

); // {"one": "hello", "two": "world"}

original = { x: { y: 1 } };

cloned = merge(true, original);

cloned.x.y++;

console.log(original.x.y, cloned.x.y); // 1, 2
zim
quelle
2
Ausgezeichnet! Vielen Dank für das Teilen.
Gor
12

Ich sehe, dass dieser Thread zu alt ist, aber ich habe meine Antwort hier nur zu Protokollierungszwecken angegeben.

In einem der obigen Kommentare haben Sie erwähnt, dass Sie in Ihrem Projekt 'express' verwenden möchten, dessen Abhängigkeitsliste die Bibliothek 'connect' enthält. Tatsächlich enthält die Bibliothek 'connect.utils' eine 'Merge'-Methode, die den Trick ausführt. Sie können also die Implementierung von Drittanbietern verwenden, ohne neue Bibliotheken von Drittanbietern hinzuzufügen.

Petr KOKOREV
quelle
11

Hier ist eine einfache Lösung, um JSON zusammenzuführen. Ich habe folgendes getan.

  • Konvertieren Sie jeden JSON mithilfe von in Zeichenfolgen JSON.stringify(object).
  • Verketten Sie alle JSON-Zeichenfolgen mit dem +Operator.
  • Ersetzen Sie das Muster /}{/gdurch","
  • Analysieren Sie die Ergebniszeichenfolge zurück zum JSON-Objekt

    var object1 = {name: "John"};
    var object2 = {location: "San Jose"};
    var merged_object = JSON.parse((JSON.stringify(object1) + JSON.stringify(object2)).replace(/}{/g,","))
    

Der resultierende zusammengeführte JSON wird sein

{name: "John", location: "San Jose"}
Manu K Mohan
quelle
Würde dies funktionieren, wenn das doppelte Anführungszeichen (Wert) {oder} enthält? Ich zögere immer, String zu hacken.
HP.
@ HP.Ja es wird funktionieren. Dies ist ein ziemlich einfacher Regex /} {/, Sie müssen sich keine Gedanken über die Manipulation von Zeichenfolgen machen. :-)
Manu K Mohan
1
Leider funktioniert es nicht, wenn object2 = {}da die letzten zu analysierenden Zeichen sind ,}. Kann durch Hinzufügen nach dem Ersetzen gelöst werden:.replace(/,}^/, '}')
htaidirt
3
Verwenden Sie eine beliebige Anzahl von Argumenten, egal ob eines mit gist.github.com/rxaviers/6734630
Rafael Xavier
Requisiten an @RafaelXavier Sein Kern macht diese Antwort zu einer brauchbaren Funktion.
Scarver2
3

Sie können auch dieses leichte npm-Paket namens absorb verwenden

Es besteht aus 27 Codezeilen, 1 KB, und verwendet die Rekursion, um tiefe Objektzusammenführungen durchzuführen.

var absorb = require('absorb');
var obj1, obj2;

obj1 = { foo: 123, bar: 456 };
obj2 = { bar: 123, key: 'value' }

absorb(obj1, obj2);

console.log(obj1); // Output: { foo: 123, bar: 123, key: 'value' }

Sie können es auch verwenden, um einen Klon zu erstellen oder Werte nur dann zu übertragen, wenn sie nicht im Quellobjekt vorhanden sind. Wie das geht, erfahren Sie unter dem angegebenen Link.

Patrick Murphy
quelle
3

Dies kann einfach mit der Object.assign () -Methode erfolgen.

 var object1 = {name: "John"};
 var object2 = {location: "San Jose"};
 var object3 = Object.assign(object1,object2);
 console.log(object3);

jetzt ist object3 {name: 'John', location: 'San Jose'}

Sushil Kumar
quelle
In Ihrem Beispiel object1wird auch geändert. Überprüfen Sie meine Antwort für weitere Details.
Ricardo Nolde
3

In Node.js gibt es eine einfache Möglichkeit, dies zu tun

var object1 = {name: "John"};
var object2 = {location: "San Jose"};

Um dies zu kombinieren / zu erweitern, können wir den ...Operator in ECMA6 verwenden

var object1 = {name: "John"};
var object2 = {location: "San Jose"};

var result = {
  ...object1,
  ...object2
}

console.log(result)

Stenal P Jolly
quelle
2

Wenn Sie spezielle Verhaltensweisen wie die Erweiterung verschachtelter Objekte oder das Ersetzen von Arrays benötigen, können Sie die Erweiterung von Node.js verwenden .

var extendify = require('extendify');

_.extend = extendify({
    inPlace: false,
    arrays : 'replace',
    isDeep: true
});

obj1 = {
    a:{
        arr: [1,2]
    },
    b: 4
};

obj2 = {
    a:{
        arr: [3]
    }
};

res = _.extend(obj1,obj2);
console.log(JSON.stringify(res)); //{'a':{'arr':[3]},'b':4}
user1928072
quelle
1
Um genau zu sein: Extendify ist nicht von Node.js. Es ist ein Paket für Node.js.
Leo Gerber
2

Lodash ist eine weitere leistungsstarke Werkzeuggürteloption für diese Art von Dienstprogrammen. Siehe: _.merge()(was rekursiv ist)

var object = {
  'a': [{ 'b': 2 }, { 'd': 4 }]
};
var other = {
  'a': [{ 'c': 3 }, { 'e': 5 }]
}; 
_.merge(object, other);
// => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } 
Joshua David
quelle
2

Verwenden Sie den Spread-Operator. Es wird in Node seit Version 8.6 unterstützt

const object1 = {name: "John"};
const object2 = {location: "San Jose"};

const obj = {...object1, ...object2}

console.log(obj)
//   {
//     "name": "John",
//     "location": "San Jose"
//   }

Khaled Bin Ein Quadir
quelle
1
Hallo Khaled, du solltest versuchen zu erklären, was der Spread-Operator tut, da dies deinen Beitrag verbessert. Erklärungen sind weitaus besser als nur die Angabe von Code. Es ist auch ein Duplikat der bereits veröffentlichten Antwort.
R. Chappell
1

Sie können Lodash verwenden

const _ = require('lodash');

let firstObject = {'email' : '[email protected]};
let secondObject = { 'name' : { 'first':message.firstName } };
_.merge(firstObject, secondObject)
Aslan Varoqua
quelle
0

Der folgende Code hilft Ihnen beim Zusammenführen von zwei JSON-Objekten mit verschachtelten Objekten.

function mergeJSON(source1,source2){
    /*
     * Properties from the Souce1 object will be copied to Source2 Object.
     * Note: This method will return a new merged object, Source1 and Source2 original values will not be replaced.
     * */
    var mergedJSON = Object.create(source2);// Copying Source2 to a new Object

    for (var attrname in source1) {
        if(mergedJSON.hasOwnProperty(attrname)) {
          if ( source1[attrname]!=null && source1[attrname].constructor==Object ) {
              /*
               * Recursive call if the property is an object,
               * Iterate the object and set all properties of the inner object.
              */
              mergedJSON[attrname] = zrd3.utils.mergeJSON(source1[attrname], mergedJSON[attrname]);
          } 

        } else {//else copy the property from source1
            mergedJSON[attrname] = source1[attrname];

        }
      }

      return mergedJSON;
}
Shibualexis
quelle
0

Ein besserer Ansatz von der richtigen Lösung hier, um das Ziel nicht zu ändern:

function extend(){
  let sources = [].slice.call(arguments, 0), result = {};
  sources.forEach(function (source) {
    for (let prop in source) {
      result[prop] = source[prop];
    }
  });
  return result;
}
Dody
quelle
0

Sie können dies inline tun, ohne folgende Variablen zu ändern:

let obj1 = { name: 'John' };
let obj2 = { surname: 'Smith' };
let obj = Object.assign({}, obj1, obj2); // { name: 'John', surname: 'Smith' }
Emre Tapcı
quelle
-3

Sei object1und object2sei zwei JSON-Objekte.

var object1 = [{"name": "John"}];
var object2 = [{"location": "San Jose"}];

object1.push(object2);

Dies wird einfach angehängt object2in object1:

[{"name":"John"},{"location":"San Jose"}]
Mohit Capitolia
quelle
Das hat das OP nicht gefragt. Sie zeigen, wie Sie ein Array von JSON-Objekten erstellen. Das OP fragte nach einer Möglichkeit, Schlüssel-Wert-Paare aus mehreren JSON-Objekten zu einem einzigen zu kombinieren.
David Makogon