比较两个对象数组,并将匹配值的元素排除到JS中的新数组中
Posted
技术标签:
【中文标题】比较两个对象数组,并将匹配值的元素排除到JS中的新数组中【英文标题】:Comparing two arrays of objects, and exclude the elements who match values into new array in JS 【发布时间】:2016-01-03 02:50:17 【问题描述】:这是我在 javascript 中的用例:
我有两个对象数组,它们的属性匹配(id 和名称)。
var result1 = [
id:1, name:'Sandra', type:'user', username:'sandra',
id:2, name:'John', type:'admin', username:'johnny2',
id:3, name:'Peter', type:'user', username:'pete',
id:4, name:'Bobby', type:'user', username:'be_bob'
];
var result2 = [
id:2, name:'John', email:'johnny@example.com',
id:4, name:'Bobby', email:'bobby@example.com'
];
var props = ['id', 'name'];
我的目标是让另一个对象数组只包含不匹配的元素。像这样:
var result = [
id:1, name:'Sandra',
id:3, name:'Peter'
];
我知道有一种方法可以做到这一点,从 result1 将每个对象与 result2 的对象进行比较,然后比较它们的键,如果不匹配,则将值放入另一个对象中,然后将其推送到新数组中,但我想知道有没有更优雅的方式,比如使用 lo-dash 或下划线或类似的东西。
谢谢!
【问题讨论】:
分享您的研究对每个人都有帮助。告诉我们您尝试了什么以及为什么它不能满足您的需求。这表明您已经花时间尝试帮助自己,它使我们免于重复明显的答案,最重要的是它可以帮助您获得更具体和相关的答案!另见how to ask 自己探索:1, 2。 试试这个:***.com/questions/368280/… 【参考方案1】:只需使用 JS 内置的 Array iteration methods 就可以了:
var result1 = [
id:1, name:'Sandra', type:'user', username:'sandra',
id:2, name:'John', type:'admin', username:'johnny2',
id:3, name:'Peter', type:'user', username:'pete',
id:4, name:'Bobby', type:'user', username:'be_bob'
];
var result2 = [
id:2, name:'John', email:'johnny@example.com',
id:4, name:'Bobby', email:'bobby@example.com'
];
var props = ['id', 'name'];
var result = result1.filter(function(o1)
// filter out (!) items in result2
return !result2.some(function(o2)
return o1.id === o2.id; // assumes unique id
);
).map(function(o)
// use reduce to make objects with only the required properties
// and map to apply this to the filtered array as a whole
return props.reduce(function(newo, name)
newo[name] = o[name];
return newo;
, );
);
document.body.innerhtml = '<pre>' + JSON.stringify(result, null, 4) +
'</pre>';
如果你经常这样做,那么一定要看看外部库来帮助你,但首先学习基础知识是值得的,这里的基础知识会很好地为你服务。
【讨论】:
【参考方案2】:在 lodash 中检查差异和异或。
【讨论】:
isArrayEqual(a1,a2);函数 isArrayEquals()【参考方案3】:使用 Lodash 也可以达到同样的效果。
var result1 = [
id:1, name:'Sandra', type:'user', username:'sandra',
id:2, name:'John', type:'admin', username:'johnny2',
id:3, name:'Peter', type:'user', username:'pete',
id:4, name:'Bobby', type:'user', username:'be_bob'
];
var result2 = [
id:2, name:'John', email:'johnny@example.com',
id:4, name:'Bobby', email:'bobby@example.com'
];
var result3 = _(result1)
.differenceBy(result2, 'id', 'name')
.map(_.partial(_.pick, _, 'id', 'name'))
.value();
console.log(result3);
<script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>
您可以使用属性“id”和“name”在两个数组之间应用差异作为在它们之间“链接”元素的一种方式来获得所需的结果。如果这些属性中的任何一个不同,则元素被认为是不同的(在您的情况下不太可能,因为 id 似乎是唯一的)。
最后,您必须映射结果以“忽略”对象的不需要的属性。
希望对你有帮助。
【讨论】:
【参考方案4】:好吧,这取决于具体情况。
但是对于只返回包含差异的数组可以通过以下方式实现,当然它取自@1983
var result = result1.filter(function (o1)
return !result2.some(function (o2)
return o1.id === o2.id; // return the ones with equal id
);
);
// if you want to be more clever...
let result = result1.filter(o1 => !result2.some(o2 => o1.id === o2.id));
【讨论】:
最后一行是整页中我最喜欢的一行! 这应该是最佳答案。单一、干净的线路,无需库。 这个答案不起作用!它返回公共元素而不是唯一元素。 要获取唯一元素而不是普通元素,请将最后一行更改为let result = result1.filter(o1 => !result2.some(o2 => o1.id === o2.id));
以返回相反的值
干净的答案,但它有 n^2 的复杂性【参考方案5】:
我已经搜索了很多解决方案,我可以在其中比较两个具有不同属性名称的对象数组(类似于左外连接)。我想出了这个解决方案。这里我使用了 Lodash。我希望这能帮到您。
var Obj1 = [
id:1, name:'Sandra',
id:2, name:'John',
];
var Obj2 = [
_id:2, name:'John',
_id:4, name:'Bobby'
];
var Obj3 = lodash.differenceWith(Obj1, Obj2, function (o1, o2)
return o1['id'] === o2['_id']
);
console.log(Obj3);
// id:1, name:'Sandra'
【讨论】:
简单明了的答案!【参考方案6】:这是另一个使用 Lodash 的解决方案:
var _ = require('lodash');
var result1 = [
id:1, name:'Sandra', type:'user', username:'sandra',
id:2, name:'John', type:'admin', username:'johnny2',
id:3, name:'Peter', type:'user', username:'pete',
id:4, name:'Bobby', type:'user', username:'be_bob'
];
var result2 = [
id:2, name:'John', email:'johnny@example.com',
id:4, name:'Bobby', email:'bobby@example.com'
];
// filter all those that do not match
var result = types1.filter(function(o1)
// if match found return false
return _.findIndex(types2, 'id': o1.id, 'name': o1.name) !== -1 ? false : true;
);
console.log(result);
【讨论】:
以上是关于比较两个对象数组,并将匹配值的元素排除到JS中的新数组中的主要内容,如果未能解决你的问题,请参考以下文章