Javascript lodash:用不同的对象数组过滤对象数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29978252/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
lodash: filter array of objects with a different array of objects
提问by mg1075
This question is specific to lodash.
这个问题特定于lodash。
Given two arrays of objects, what is the best wayto filter one array with the objects of the other array? I have attempted to put forth a scenario below, and the way I have gone about doing this is using two .forEachloops, but I would like to know if using lodash there is a better way to go about this type of filtering.
给定两个对象数组,用另一个数组的对象过滤一个数组的最佳方法是什么?我试图在下面提出一个场景,我这样做的方法是使用两个.forEach循环,但我想知道使用 lodash 是否有更好的方法来进行这种类型的过滤。
Example示例
对象的主要源数组是
usersusers.var users = [
{ 'user': 'barney', 'age': 36, 'active': true },
{ 'user': 'joe', 'age': 40, 'active': false },
{ 'user': 'fred', 'age': 50, 'active': false },
{ 'user': 'fred', 'age': 60, 'active': false },
{ 'user': 'fred', 'age': 70, 'active': false },
{ 'user': 'fred', 'age': 22, 'active': false },
{ 'user': 'fred', 'age': 25, 'active': false },
{ 'user': 'barney', 'age': 40, 'active': false },
{ 'user': 'pebbles', 'age': 1, 'active': true }
];
The array of objects that will filter the usersarray is called others.
将过滤数组的对象users数组称为others。
var others = [
{ 'user': 'fred', 'age': 60 },
{ 'user': 'fred', 'age': 70},
{ 'user': 'fred', 'age': 22}
];
The desired result based on othersfiltering usersis:
基于others过滤的期望结果users是:
[
{ 'user': 'fred', 'age': 60, 'active': false },
{ 'user': 'fred', 'age': 70, 'active': false },
{ 'user': 'fred', 'age': 22, 'active': false }
];
Here is one way to obtain the desired result.
这是获得所需结果的一种方法。
var result = [];
_.forEach(users, function (n, key) {
_.forEach(others, function (n2, key2) {
if (n.user === n2.user && n.age === n2.age) {
result.push(n);
}
});
});
console.log(result);
Here is the example on jsbin.
http://jsbin.com/hapariviya/1/edit?html,js,console,output
这是 jsbin 上的示例。
http://jsbin.com/hapariviya/1/edit?html,js,console,output
采纳答案by Cory Danielson
You can index the others, and then get the desired results without having to nest loops. It should be a relatively efficient solution, regardless of the amount of data:
您可以索引其他的,然后无需嵌套循环即可获得所需的结果。无论数据量如何,它都应该是一个相对高效的解决方案:
// index others by "user + age"
var lookup = _.keyBy(others, function(o) { return o.user + o.age.toString() });
// find all users where "user + age" exists in index, one loop, quick lookup. no nested loops
var result = _.filter(users, function(u) {
return lookup[u.user + u.age.toString()] !== undefined;
});
This gives the same result:
这给出了相同的结果:
[
{ 'user': 'fred', 'age': 60, 'active': false },
{ 'user': 'fred', 'age': 70, 'active': false },
{ 'user': 'fred', 'age': 22, 'active': false }
];
Interestingly, your original solution was the most performant of all of these answers.
有趣的是,您的原始解决方案是所有这些答案中性能最高的。
The performance concerns are pretty negligible here. In most cases, the DOM interaction is the main performance bottleneck of the front-end. If you were to run this against huge datasets and noticed the locking, you'd definitely want to optimize it further by using for loops instead of iterating with lodash functions.... but you won't typically come across that kind of data in JavaScript... SQL and others would handle it better.
性能问题在这里可以忽略不计。大多数情况下,DOM 交互是前端的主要性能瓶颈。如果您要针对庞大的数据集运行它并注意到锁定,您肯定希望通过使用 for 循环而不是使用 lodash 函数进行迭代来进一步优化它......但您通常不会在JavaScript ... SQL 和其他人会处理得更好。
回答by Chavdar Slavov
Here is cleaner way i can think of:
这是我能想到的更清洁的方法:
var result = _.flatten(_.map(others, function(item){
return _.filter(users, item);
}));
Edit:Apologies JS Binoutput was obfuscating the nested array.
编辑:道歉JS Bin输出混淆了嵌套数组。
回答by Georgian-Sorin Maxim
Using ES6 fat arrows and lodash's reject:
使用 ES6 粗箭头和 lodash 的拒绝:
const result = _.reject(users, (item) => _.find(others, { user: item.user }));
回答by Christian
var result = _.flatten(_.map(others, function(other){return _.where(users, other);}));
回答by Andrien Pecson
If you are using lodash and ES6 syntax.
如果您使用 lodash 和 ES6 语法。
const users = [
{ 'user': 'barney', 'age': 36, 'active': true },
{ 'user': 'joe', 'age': 40, 'active': false },
{ 'user': 'fred', 'age': 50, 'active': false },
{ 'user': 'fred', 'age': 60, 'active': false },
{ 'user': 'fred', 'age': 70, 'active': false },
{ 'user': 'fred', 'age': 22, 'active': false },
{ 'user': 'fred', 'age': 25, 'active': false },
{ 'user': 'barney', 'age': 40, 'active': false },
{ 'user': 'pebbles', 'age': 1, 'active': true }
];
const filters = [
{ 'user': 'fred', 'age': 60, 'active': false },
{ 'user': 'fred', 'age': 70, 'active': false },
{ 'user': 'fred', 'age': 22, 'active': false }
];
_.filter(users, ({user, age, active}) => {
return _.findIndex(filters, ({user:filterUser, age:filterAge, active:filterActive}) => { return (user == filterUser && age == filterAge && active == filterActive) }) >= 0;
})

