当我在标题中描述我的问题时,我需要实现以下算法:
我得到了一些元素,例如:
let arr1 = [
{id:1, foo1: '...', foo2: '...'},
{id:2, foo1: '...', foo2: '...'},
{id:3, foo1: '...', foo2: '...'},
];
在我的应用程序的某个地方,我得到了另一个数组arr2,它可以包含已经在arr1中的元素。
let arr2 = [
{id:1, foo1: '...', foo2: '...'},
{id:4, foo1: '...', foo2: '...'},
{id:5, foo1: '...', foo2: '...'},
];
如果arr1包含arr2的每个元素,我需要从arr1中排除这些元素。在第二种情况下,arr2包含至少一个也不在arr1中的元素,arr2的所有元素都将附加到arr1。
我尝试了lodash的函数_.xorBy(arr1, arr2, 'id')
,它在所有情况下都不起作用。我在lodash的文档中寻找了另外一个函数来满足我的需求,但我没有找到任何东西。
这是我的预期行为(我只使用数字但在实际应用中有这个ID的对象):
你能帮助我解决我的问题,或者展示一些优雅的方法吗?谢谢你的建议。
答案 0 :(得分:3)
如果arr2
和arr1
之间的_.difference()
数组长度大于0
,则返回_.union()
个数组。如果不在_.difference()
和arr1
之间返回arr2
。
注1: _.difference(arr2, arr1)
不等于_.difference(arr1, arr2)
,因为结果值的顺序和引用由第一个数组确定。
注2:该示例使用基元数组。对于对象数组,请使用By
版本 - _.differenceBy()
和_.unionBy()
,并使用属性iteratee简写 - _.differenceBy(arr1, arr2, 'id')
。
const incEx = (arr1, arr2) =>
_.difference(arr2, arr1).length > 0 ?
_.union(arr1, arr2)
:
_.difference(arr1, arr2);
console.log(incEx([1,2,3,4,5], [1,2,3]));
console.log(incEx([1,2,3,4,5], [1,2,6]));

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
&#13;
答案 1 :(得分:1)
使用Set
的简单Javascript解决方案。
function merge(array1, array2) {
var ids1 = new Set(array1.map(({ id }) => id)),
ids2 = new Set(array2.map(({ id }) => id));
return array2.every(({ id }) => ids1.has(id))
? array1.filter(({ id }) => !ids2.has(id))
: array1.concat(array2.filter(({ id }) => !ids1.has(id)));
}
var array1 = [{ id: 1 }, { id: 2 }, { id: 3 }],
array2 = [{ id: 1 }, { id: 4 }, { id: 5 }];
console.log(merge(array1, array2));
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 2 :(得分:0)
如果arr1包含arr2的每个元素,我需要排除这些 来自arr1的元素。
检查arr2
arr1
var hasAllValues = arr2.every( s => !!arr1.find( t => t.id == s.id ) )
如果hasAllValues
中包含所有arr2
,则 arr1
为真
使用filter
删除arr1
,
arr1 = arr1.filter( s => arr2.find( t => t.id == s.id ) );
在第二种情况下,arr2包含至少一个元素 也不在arr1中,arr2的所有元素都将附加到arr1。
使用
查找不是arr1的arr2的值var arr3 = arr2.filter( s => !!arr1.find( t => t.id == s.id ) );
arr1 = arr1.concat( arr3 );
因此,最终的解决方案是
var hasAllValues = arr2.every( s => !!arr1.find( t => t.id == s.id ) )
if ( hasAllValues )
{
arr1 = arr1.filter( s => !arr2.find( t => t.id == s.id ) );
}
else
{
var arr3 = arr2.filter( s => !arr1.find( t => t.id == s.id ) );
arr1 = arr1.concat( arr3 );
}
方案1的演示
let arr1 = [{
id: 1
},
{
id: 2
},
{
id: 3
},
{
id: 4
}
];
let arr2 = [{
id: 1
},
{
id: 4
}
];
var hasAllValues = arr2.every(s => !!arr1.find(t => t.id == s.id))
if (hasAllValues) {
arr1 = arr1.filter(s => !arr2.find(t => t.id == s.id));
} else {
var arr3 = arr2.filter(s => !arr1.find(t => t.id == s.id));
//console.log(arr3)
arr1 = arr1.concat(arr3);
}
console.log(arr1);
&#13;
方案2的演示
let arr1 = [{
id: 1
},
{
id: 2
},
{
id: 3
}
];
let arr2 = [{
id: 1
},
{
id: 4
},
{
id: 5
}
];
var hasAllValues = arr2.every(s => !!arr1.find(t => t.id == s.id))
if (hasAllValues) {
arr1 = arr1.filter(s => !arr2.find(t => t.id == s.id));
} else {
var arr3 = arr2.filter(s => !arr1.find(t => t.id == s.id));
//console.log(arr3)
arr1 = arr1.concat(arr3);
}
console.log(arr1);
&#13;