2つのRESTサービスで提供される2つのjson配列を組み合わせる必要があります。同じ「id」を持つエントリは一緒に属します。
json1 = [{id:1,name:'aaa'},
{id:5,name:'ccc'},
{id:3,name:'bbb'}
];
json2 = [{id:3,parameter1:'x', parameter2:'y', parameter3:'z'},
{id:1,parameter1:'u', parameter2:'v', parameter3:'w'},
{id:5,parameter1:'q', parameter2:'w', parameter3:'e'}
];
私は次の方法でjavascriptの結合/コピー/クローン化されたjson配列が必要です(angular2の私のモデル):
json3 = [{id:3,name:'bbb',parameter1:'x', parameter2:'y', parameter3:'z'},
{id:1,name:'aaa', parameter1:'u', parameter2:'v', parameter3:'w'},
{id:5,name:'ccc', parameter1:'q', parameter2:'w', parameter3:'e'}
];
それらを組み合わせる方法はありますか?パラメーター名は正確に定義されておらず、可変パラメーターベクトルを使用する必要があります。
ループごとに混合して試してみました。とてもいようです。
2つだけでなく、任意の数の配列を取り込むことができるように記述したい場合は、 arguments を利用して、次のようなことを行うことができます。
var json1 = [{id:1,name:'aaa'},{id:5,name:'ccc'},{id:3,name:'bbb'}];
var json2 = [{id:3,parameter1:'x', parameter2:'y', parameter3:'z'},
{id:1,parameter1:'u', parameter2:'v', parameter3:'w'},
{id:5,parameter1:'q', parameter2:'w', parameter3:'e'}
];
function joinObjects() {
var idMap = {};
// Iterate over arguments
for(var i = 0; i < arguments.length; i++) {
// Iterate over individual argument arrays (aka json1, json2)
for(var j = 0; j < arguments[i].length; j++) {
var currentID = arguments[i][j]['id'];
if(!idMap[currentID]) {
idMap[currentID] = {};
}
// Iterate over properties of objects in arrays (aka id, name, etc.)
for(key in arguments[i][j]) {
idMap[currentID][key] = arguments[i][j][key];
}
}
}
// Push properties of idMap into an array
var newArray = [];
for(property in idMap) {
newArray.Push(idMap[property]);
}
return newArray;
}
var json3 = joinObjects(json1, json2);
2つのワンライナー:
ダッシュ付き:
res = _(json1).concat(json2).groupBy('id').map(_.spread(_.assign)).value();
eS2015で:
res = json2.map(x => Object.assign(x, json1.find(y => y.id == x.id)));
ES2015 georgの答えは素晴らしい作品です。
json1 = [
{id:1, test: 0},
{id:2, test: 0},
{id:3, test: 0},
{id:4, test: 0},
{id:5, test: 0}
];
json2 = [
{id:1, test: 1},
{id:3, test: 1},
{id:5, test: 1}
];
json1.map(x => Object.assign(x, json2.find(y => y.id == x.id)));
結果:
{id:1, test: 1},
{id:2, test: 0},
{id:3, test: 1},
{id:4, test: 0},
{id:5, test: 1}
ネストされたループを使用して、対応する要素を見つけてマージします。
for (var i = 0; i < json1.length; i++) {
var id = json1[i].id;
for (var j = 0; j < json2.length; j++) {
if (json2[j].id = id) {
for (var key in json2[j]) {
json1[i][key] = json2[j][key];
}
break;
}
}
}
最後に、json1
には結合された要素が含まれます。
上記のコードは、json2
のすべての要素がjson1
の何かと一致することを前提としています。 json2
に余分な要素がある場合、それらをjson1
にコピーするには追加のループが必要になります。
これは、id(スパース配列)をキーとするインデックスを最初に構築して、一致するid値を持つオブジェクトを検出および結合する方法です、最後に連結されて通常の配列に戻ります。
json3 = json1.concat(json2).reduce(function(index, obj) {
if (!index[obj.id]) {
index[obj.id] = obj;
} else {
for (prop in obj) {
index[obj.id][prop] = obj[prop];
}
}
return index;
}, []).filter(function(res, obj) {
return obj;
});
json1 = [
{id:1,name:'aaa'},
{id:5,name:'ccc'},
{id:3,name:'bbb'}
];
json2 = [
{id:3,parameter1:'x', parameter2:'y', parameter3:'z'},
{id:1,parameter1:'u', parameter2:'v', parameter3:'w'},
{id:5,parameter1:'q', parameter2:'w', parameter3:'e'}
];
json3 = json1.concat(json2).reduce(function(index, obj) {
if (!index[obj.id]) {
index[obj.id] = obj;
} else {
for (prop in obj) {
index[obj.id][prop] = obj[prop];
}
}
return index;
}, []).filter(function(res, obj) {
return obj;
});
document.write('<pre>', JSON.stringify(json3, null, 4), '</pre>');
ブラウザが Object.assign をサポートしている場合:
json3 = json1.concat(json2).reduce(function(index, obj) {
index[obj.id] = Object.assign({}, obj, index[obj.id]);
return index;
}, []).filter(function(res, obj) {
return obj;
});
forEachおよびfilterを使用して、要件を解決できます。
vehicleArray1 = [{id:1, name: "a"},{id:2, name: "b"},{id:3, name:"c"}];
vehicleArray2 = [{id:1, type: "two wheeler"},{id:2, type: "four wheeler"},{id:3, type:"six wheeler"}];
var outArr = [];
vehicleArray1.forEach(function(value) {
var existing = vehicleArray2.filter(function(v, i) {
return (v.id == value.id);
});
if (existing.length) {
value.type = existing[0].type;
outArr.Push(value)
} else {
value.type = '';
outArr.Push(value);
}
});
console.log(outArr)
let json1 = [
{id:1,name:'aaa'},
{id:5,name:'ccc'},
{id:3,name:'bbb'}
];
let json2 = [
{id:3,parameter1:'x', parameter2:'y', parameter3:'z'},
{id:1,parameter1:'u', parameter2:'v', parameter3:'w'},
{id:5,parameter1:'q', parameter2:'w', parameter3:'e'}
];
let result = json1.map(obj => {
let data = json2.find(item => item.id === obj.id);
return {...obj, ...data}
});
これはあなたのためにそれを行う必要があります。コードがそれ自体で意味をなすことを願っています。この例では、常にjson1
上の値json2
値が両方存在する場合。それを変更したい場合は、オブジェクト参照を切り替える必要があります(src[i]
およびobj[j]
)最も内側のループ。
// Will take src, and merge in the contents of obj.
// Expects an array of objects for both.
// Will keep src values in favour of obj values.
function extend(src, obj) {
// Loop the src, in this case json1
for (var i = 0; i < src.length; i++) {
// For every loop of json1, also loop json2
for (var j = 0; j < obj.length; j++) {
// If we have matching IDs operate on this pair
if (src[i].id == obj[j].id) {
// For every key in the object being merged in,
// if the key exists in src, ignore new value.
// if the doesn't exist in src, take the new value.
for (var key in obj[j]) {
src[i][key] = src[i].hasOwnProperty(key) ? src[i][key] : obj[j][key];
}
// We found our matching pair, so break out of the json2 loop
break;
}
}
}
return src;
}
// -------------------------------------------
var json1 = [{
id: 1,
name: 'aaa'
},{
id: 5,
name: 'ccc'
},{
id: 3,
name: 'bbb'
}];
var json2 = [{
id: 3,
parameter1: 'x',
parameter2: 'y',
parameter3: 'z'
},{
id: 1,
parameter1: 'u',
parameter2: 'v',
parameter3: 'w'
},{
id: 5,
parameter1: 'q',
parameter2: 'w',
parameter3: 'e'
}];
var json3 = extend(json1, json2);
// ---------------------------------------------
var pre = document.getElementById('out');
pre.innerHTML = JSON.stringify(json3);
<pre id="out"></pre>