これらのようなJSON
が複数あります
var object1 = {name: "John"};
var object2 = {location: "San Jose"};
それらはネストまたはそのようなものではありません。基本的に異なるフィールド。次のように、それらを1つのJSON
innode.jsに結合する必要があります。
{name: "John", location: "San Jose"}
jQueryを使用できます。ブラウザーでの実際の例を次に示します。
http://jsfiddle.net/qhoc/agp54/
しかし、node.jsでこれを行う場合、jQueryをロードしたくありません(これは少し使い過ぎですが、プラスnode.jsのjQueryは、私のWindowsマシンでは動作しません)。
jQueryなしで$.extend()
と同様のことをする簡単な方法はありますか?
通常のループですか?
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);
それが基本的な出発点です。 hasOwnProperty
チェックなどを追加したり、複数のソースオブジェクトに同じ識別子のプロパティがある場合を処理するロジックを追加したい場合があります。
実施例 です。
サイドノート:「JSON」と呼ぶものは、実際には通常のJavaScriptオブジェクトです。 JSONは、JavaScriptと何らかの構文を共有する単なるテキスト形式です。
浅いマージのこのような単純なユースケースのために、車輪を再発明する必要はありません。
Object.assign()メソッドは、列挙可能なすべてのプロパティの値を1つ以上のソースオブジェクトからターゲットオブジェクトにコピーするために使用されます。ターゲットオブジェクトを返します。
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
_extend
は、内部NodeJSモジュールの外部で使用されることを意図していませんでした。とにかくコミュニティはそれを見つけて使用しました。非推奨であり、新しいコードで使用しないでください。 JavaScriptには、Object.assign
を介した非常に類似した組み込み機能が付属しています。
version 8.6 であるため、Node.jsで spread operator をネイティブに使用することができます。以下の例:
let o1 = { a: 1 };
let o2 = { b: 2 };
let obj = { ...o1, ...o2 }; // { a: 1, b: 2 }
ただし、Object.assign
は引き続き機能します。
PS1 : deep merging (内部オブジェクトデータが任意の深さで再帰的にマージされる)に実際に興味がある場合、 deepmerge 、 assign-deep 、または lodash.merge のようなパッケージを使用できます。これらは非常に小さくて使いやすいです。
PS2 :Object.assignはNode.js の0.Xバージョンでは動作しないことに注意してください。これらのバージョンのいずれかを使用している場合(、今は実際にすべきではありません)、上記のNode.jsリンクに示すようにrequire("util")._extend
を使用できます-詳細については、 この同じ質問に対するtobymackenzieの回答 を確認してください。
Node version> = 4を使用する場合は、Object.assign()
を使用します( Ricardo Noldeの回答 を参照)。
Node 0.xを使用している場合、組み込みのutil._extendがあります。
var extend = require('util')._extend
var o = extend({}, {name: "John"});
extend(o, {location: "San Jose"});
ディープコピーは行わず、一度に2つの引数のみを許可しますが、組み込まれています。ノードでオブジェクトを複製することについての質問でこれについて言及しました: https://stackoverflow.com/a/15040626 。
「プライベート」メソッドの使用が心配な場合は、いつでもプロキシすることができます。
// myutil.js
exports.extend = require('util')._extend;
消えた場合は、独自の実装に置き換えます。これは(およそ)それらの実装です:
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;
};
nderscoreのextend
は、Jamesがコメントしたように、これを達成する最も簡単で迅速な方法です。
下線を使用した例を次に示します。
var _ = require('underscore'), // npm install underscore to install
object1 = {name: "John"},
object2 = {location: "San Jose"};
var target = _.extend(object1, object2);
オブジェクト1は、オブジェクト2のプロパティを取得し、返されてターゲットに割り当てられます。 object1が変更されているかどうかに応じて、次のようにすることもできます。
var target = {};
_.extend(target, object1, object2);
merge を使用します。
$ npm install merge
サンプルコード:
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
このスレッドは古すぎることがわかりましたが、ここではログを記録する目的で答えを示します。
上記のコメントの1つで、依存関係リストに「connect」ライブラリがあるプロジェクトで「express」を使用したいと述べました。実際、「connect.utils」ライブラリには、このトリックを実行する「merge」メソッドが含まれています。そのため、新しいサードパーティライブラリを追加せずにサードパーティの実装を使用できます。
JSONをマージする簡単なソリューションを次に示します。私は次のことをしました。
JSON.stringify(object)
を使用して、各JSONを文字列に変換します。+
演算子を使用して、すべてのJSON文字列を連結します。/}{/g
を","
に置き換えます結果文字列を解析してJSONオブジェクトに戻す
var object1 = {name: "John"};
var object2 = {location: "San Jose"};
var merged_object = JSON.parse((JSON.stringify(object1) + JSON.stringify(object2)).replace(/}{/g,","))
結果のマージされたJSONは
{name: "John", location: "San Jose"}
Node.jsでそれを行う簡単な方法があります
var object1 = {name: "John"};
var object2 = {location: "San Jose"};
これを結合/拡張するには、ECMA6で...
演算子を使用できます
var object1 = {name: "John"};
var object2 = {location: "San Jose"};
var result = {
...object1,
...object2
}
console.log(result)
absorb と呼ばれるこの軽量のnpmパッケージを使用することもできます
これは27行のコード、1kbであり、再帰を使用して深いオブジェクトマージを実行します。
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' }
また、クローンを作成したり、ソースオブジェクトに値が存在しない場合にのみ値を転送したりすることもできます。これを行う方法については、提供されているリンクで詳しく説明しています。
Object.assign()メソッドを使用して簡単に実行できます-
var object1 = {name: "John"};
var object2 = {location: "San Jose"};
var object3 = Object.assign(object1,object2);
console.log(object3);
現在、object3は{名前: 'John'、場所: 'San Jose'}
ネストされたオブジェクト拡張や配列置換などの特別な動作が必要な場合は、Node.jsの extendify を使用できます。
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}
スプレッド演算子を使用します。バージョン8.6以降、Nodeでサポートされています
const object1 = {name: "John"};
const object2 = {location: "San Jose"};
const obj = {...object1, ...object2}
console.log(obj)
// {
// "name": "John",
// "location": "San Jose"
// }
以下のコードは、ネストされたオブジェクトを持つ2つのJSONオブジェクトをマージするのに役立ちます。
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;
}
Lodashを使用できます
const _ = require('lodash');
let firstObject = {'email' : '[email protected]};
let secondObject = { 'name' : { 'first':message.firstName } };
_.merge(firstObject, secondObject)
次のような変数を変更せずに、インラインで実行できます。
let obj1 = { name: 'John' };
let obj2 = { surname: 'Smith' };
let obj = Object.assign({}, obj1, obj2); // { name: 'John', surname: 'Smith' }
ターゲットを変更しないための正しいソリューションからのより良いアプローチ:
function extend(){
let sources = [].slice.call(arguments, 0), result = {};
sources.forEach(function (source) {
for (let prop in source) {
result[prop] = source[prop];
}
});
return result;
}