我需要组合两个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'}
];
有没有办法将它们结合起来?参数名称未精确定义,需要使用可变参数向量。
我尝试用每个循环混合。对我来说非常难看。
答案 0 :(得分:35)
两个单行:
用lodash:
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)));
答案 1 :(得分:6)
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}
答案 2 :(得分:3)
如果您想要编写它以便可以接收任意数量的数组,而不仅仅是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);
答案 3 :(得分: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
。
答案 4 :(得分:1)
使用 forEach 和过滤器,我们可以解决此问题。
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)
&#13;
答案 5 :(得分:1)
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}
});
答案 6 :(得分:1)
JavaScript:
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 json3 = [];
json1.forEach((j1) => {
json2.forEach((j2) => {
if (j1.id === j2.id) {
json3.push({ ...j1, ...j2 });
}
});
});
console.log(JSON.stringify(json3));
.as-console-wrapper { top: 0; max-height: 100% !important; }
答案 7 :(得分:0)
这应该为你做。我希望代码本身有意义。如果两者都存在,则此示例将始终使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);
&#13;
<pre id="out"></pre>
&#13;
答案 8 :(得分:0)
这是一种首先构建由 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;
});
答案 9 :(得分:0)
这是使用 object-lib 的通用解决方案。
优点是您可以完全控制对象的合并方式,并且支持嵌套和多个嵌套的 groupBy。
// const objectLib = require('object-lib');
const { Merge } = objectLib;
const json1 = [{ id: 1, name: 'aaa' }, { id: 5, name: 'ccc' }, { id: 3, name: 'bbb' }];
const 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' }];
const groupById = Merge({ '[*]': 'id' });
console.log(groupById(json1, json2));
// => [ { id: 1, name: 'aaa', parameter1: 'u', parameter2: 'v', parameter3: 'w' }, { id: 5, name: 'ccc', parameter1: 'q', parameter2: 'w', parameter3: 'e' }, { id: 3, name: 'bbb', parameter1: 'x', parameter2: 'y', parameter3: 'z' } ]
const o1 = [{ id: 1, children: [{ type: 'A' }, { type: 'C' }] }, { id: 5 }];
const o2 = [{ id: 1, children: [{ type: 'A' }, { type: 'B' }] }, { id: 3 }];
console.log(groupById(o1, o2));
// => [ { id: 1, children: [ { type: 'A' }, { type: 'C' }, { type: 'A' }, { type: 'B' } ] }, { id: 5 }, { id: 3 } ]
const groupByCustom = Merge({
'[*]': 'id',
'[*].children[*]': 'type'
});
console.log(groupByCustom(o1, o2));
// => [ { id: 1, children: [ { type: 'A' }, { type: 'C' }, { type: 'B' } ] }, { id: 5 }, { id: 3 } ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-lib@2.0.0"></script>
免责声明:我是object-lib
的作者答案 10 :(得分:0)
洛达什
const json1 = [{ id: 1, name: 'aaa' }, { id: 3, name: 'bbb' },
{ id: 5, name: 'ccc' }];
const json2 = [{ id: 3, parameters: 'xyz' },
{ id: 5, parameters: 'qwe' }, { id: 1, parameters: 'uvw' }];
console.log('json1 BEFORE:\n' + JSON.stringify(json1));
const result_Lodash =
_(json1).concat(json2).groupBy('id').map(_.spread(_.assign)).value();
console.log('Result, Lodash:\n' + JSON.stringify(result_Lodash));
console.log('json1 AFTER:\n' + JSON.stringify(json1));
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src=
"https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.js"></script>
Object.assign
const json1 = [{ id: 1, name: 'aaa' }, { id: 3, name: 'bbb' },
{ id: 5, name: 'ccc' }];
const json2 = [{ id: 3, parameters: 'xyz' },
{ id: 5, parameters: 'qwe' }, { id: 1, parameters: 'uvw' }];
console.log('json2 BEFORE:\n' + JSON.stringify(json2));
const result_Object_assign =
json2.map(x => Object.assign(x, json1.find(y => y.id === x.id)));
console.log('Object.assign:\n' + JSON.stringify(result_Object_assign));
console.log('json2 AFTER:\n' + JSON.stringify(json2));
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src=
"https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.js"></script>
值得指出的是,对于这两种解决方案,第一个的内容
/ left 数组已更改。
运行代码片段以查看它。
例如,Object.assign(x, json1.find(y => y.id === x.id))
复制
将数据复合到 x
中的对象 json2
,json2
中的对象是
因此通过.map()
更新。
标识符 result_Object_assign
实际上只是另一个指针
指向与 json2
指向的数组完全相同的数组 - 没有新对象
已创建!
Object.assign 不改变输入数组
如果您不想更改任何输入数组,只需创建一个新的
数组,如下图:
const json1 = [{ id: 1, name: 'aaa' }, { id: 3, name: 'bbb' },
{ id: 5, name: 'ccc' }];
const json2 = [{ id: 3, parameters: 'xyz' },
{ id: 5, parameters: 'qwe' }, { id: 1, parameters: 'uvw' }];
console.log('json2 BEFORE:\n' + JSON.stringify(json2));
const result_Object_assign =
json2.map(x => Object.assign({}, x, json1.find(y => y.id === x.id)));
console.log('Object.assign:\n' + JSON.stringify(result_Object_assign));
console.log('json2 AFTER:\n' + JSON.stringify(json2));
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src=
"https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.js"></script>
答案 11 :(得分:0)
结果 1:使用 reduce 并匹配 ID。
先将两个数组串联成一个数组,然后检测合并
具有匹配 id 的对象。最后过滤掉所有 null
值。
结果 2:使用 reduce 和 Object.assign。
const json1 = [{id:1,name:'aaa'},{id:3,name:'bbb'},{id:5,name:'ccc'}];
const json2 =
[{id:3,parameters:'xyz'},{id:5,parameters:'qwe'},{id:1,parameters:'uvw'}];
const json7 = json1.concat(json2);
console.log(' json7:\n'+JSON.stringify(json7));
const Result_1 =
json7.reduce((accumulator, obj) => {
if (!accumulator[obj.id]) {
accumulator[obj.id] = obj;
} else {
for (proprty in obj) { accumulator[obj.id][proprty] = obj[proprty];}
}
return accumulator;
}, []).filter(x => x);
console.log('\n Result_1:\n' + JSON.stringify(Result_1));
const Result_2 =
json1.concat(json2).reduce((accumulator, obj) => {
accumulator[obj.id] = Object.assign({}, accumulator[obj.id], obj);
return accumulator;
}, []).filter(x => x);
console.log('\n Result_2:\n' + JSON.stringify(Result_2));
.as-console-wrapper { max-height: 100% !important; top: 0; }