[英]Merge two arrays of objects with override on key value
I am trying to merge data from json that comes in array of objects.我正在尝试合并来自对象数组中的 json 数据。 I was using the underscore solution from here merge two json object based on key value in javascript , but it turns out it doesnt override existing items which I need to do as well now.
我正在使用这里的下划线解决方案, 根据 javascript 中的键值合并两个 json 对象,但事实证明它不会覆盖我现在也需要做的现有项目。
The result should be all items of array 1 in the same order, overriden by array 2 where id = id.结果应该是数组 1 的所有项目以相同的顺序,被数组 2 覆盖,其中 id = id。 Items in array 2 that does not exist in array 1 should be pushed to the end of the result.
数组 2 中不存在于数组 1 中的项目应被推送到结果的末尾。
First array:第一个数组:
[
{id: 8, category: "A"}
{id: 2, category: "D"}
{id: 5, category: "C"}
{id: 9, category: "B"}
]
Second array:第二个数组:
[
{id: 1, category: "X"}
{id: 2, category: "Y"}
]
Expected result:预期结果:
[
{id: 8, category: "A"}
{id: 2, category: "Y"}
{id: 5, category: "C"}
{id: 9, category: "B"}
{id: 1, category: "X"}
]
Use filter
, find
and concat
使用
filter
, find
和concat
Given that鉴于
var arr1 = [
{id: 8, category: "A"},
{id: 2, category: "D"},
{id: 5, category: "C"},
{id: 9, category: "B"}
];
var arr2 = [
{id: 12, category: "X"},
{id: 2, category: "Y"}
];
If the order is not important如果顺序不重要
var output = arr2.concat(
arr1.filter( s =>
!arr2.find( t => t.id == s.id )
)//end filter
);//end concat
Demo演示
var arr1 = [{ id: 8, category: "A" }, { id: 2, category: "D" }, { id: 5, category: "C" }, { id: 9, category: "B" } ]; var arr2 = [{ id: 12, category: "X" }, { id: 2, category: "Y" } ]; var output = arr2.concat( arr1.filter(s => !arr2.find(t => t.id == s.id) ) //end filter ); //end concat console.log(output);
If the order is important如果订单很重要
var output = arr1.map(
s => arr2.find(
t => t.id == s.id ) || s
).concat( //end map of arr1
arr2.filter(
s => !arr1.find( t => t.id == s.id )
) //end filter
);//end concat
Demo演示
var arr1 = [{ id: 8, category: "A" }, { id: 2, category: "D" }, { id: 5, category: "C" }, { id: 9, category: "B" } ]; var arr2 = [{ id: 12, category: "X" }, { id: 2, category: "Y" } ]; var output = arr1.map( s => arr2.find( t => t.id == s.id) || s ).concat( //end map of arr1 arr2.filter( s => !arr1.find(t => t.id == s.id) ) //end filter ); //end concat console.log(output);
You could use a Map
as closure and store the index of the result array for this id
.您可以使用
Map
作为闭包并为此id
存储结果数组的索引。
var first = [{ id: 8, category: "A" }, { id: 2, category: "D" }, { id: 5, category: "C" }, { id: 9, category: "B" }], second = [{ id: 12, category: "X" }, { id: 2, category: "Y" }], result = [first, second].reduce((m => (r, a) => { a.forEach(o => { if (m.has(o.id)) { r[m.get(o.id)] = o; return; } m.set(o.id, r.push(o) - 1); }); return r; })(new Map), []); console.log(result);
You can set a loop on your secondArray
and check each object with id
value against object with id
of firstArray
.您可以在
secondArray
上设置一个循环,并根据id
为firstArray
对象检查每个具有id
值的对象。 If you find a match then simply replace the object else push the object:如果找到匹配项,则只需替换对象,否则推送对象:
var firstArray = [ {id: 8, category: "A"}, {id: 2, category: "D"}, {id: 5, category: "C"}, {id: 9, category: "B"} ]; var secondArray = [ {id: 12, category: "X"}, {id: 2, category: "Y"} ]; secondArray.forEach((obj)=>{ var match = false; for(var i=0; i<firstArray.length; i++){ if(firstArray[i].id === obj.id){ match = true; firstArray[i] = obj; break; } } if(!match){ firstArray.push(obj); } }); console.log(firstArray);
You can use a forEach
to iterate through second
array.您可以使用
forEach
遍历second
数组。 For each object with the same id in the first array, update the category
otherwise push in the new array.对于第一个数组中具有相同 id 的每个对象,更新
category
否则推入新数组。
const first = [{id: 8, category: "A"},{id: 2, category: "D"},{id: 5, category: "C"},{id: 9, category: "B"}], second = [{id: 12, category: "X"},{id: 2, category: "Y"}], merged = [...first]; second.forEach(o => { let obj = first.find(({id,category}) => id === o.id); obj ? obj.category = o.category : merged.push({...o}); }); console.log(merged);
我认为减少更好
first.reduce((res, item) => res.filter(i => i.id !== item.id).concat(item), second);
Using underscore I managed to come up with this answer my own question.使用下划线我设法想出了这个答案我自己的问题。 It is probably not the most efficent
这可能不是最有效的
const newarr = _.map(arr1, obj1 => {
const r = _.find(arr2, obj2 => {
return obj1[match] === obj2[match]
})
if (typeof r === 'undefined') {
return obj1
} else {
return r
}
})
_.each(arr2, obj => {
if (_.indexOf(arr1, _.findWhere(arr1, {id: obj.id})) === -1) {
newarr.push(obj)
}
})
这应该有效:
const newArr = second.reduce((res, item) => res.filter(i => i.id !== item.id).concat(item), first);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.