lodash:使用不同的对象数组过滤对象数组
lodash: filter array of objects with a different array of objects
此问题特定于 lodash。
给定两个对象数组,用另一个数组的对象过滤一个数组的最佳方法是什么?我试图在下面提出一个场景,我这样做的方法是使用两个 .forEach
循环,但我想知道使用 lodash 是否有更好的方法来处理这种类型的过滤.
例子
对象的主要源数组是 users
.
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 }
];
将过滤 users
数组的对象数组称为 others
。
var others = [
{ 'user': 'fred', 'age': 60 },
{ 'user': 'fred', 'age': 70},
{ 'user': 'fred', 'age': 22}
];
基于others
过滤users
的期望结果是:
[
{ 'user': 'fred', 'age': 60, 'active': false },
{ 'user': 'fred', 'age': 70, 'active': false },
{ 'user': 'fred', 'age': 22, 'active': false }
];
这是获得所需结果的一种方法。
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);
这里是jsbin上的例子。
http://jsbin.com/hapariviya/1/edit?html,js,console,output
这是我能想到的更简洁的方法:
var result = _.flatten(_.map(others, function(item){
return _.filter(users, item);
}));
编辑:
抱歉 JS Bin 输出混淆了嵌套数组。
var result = _.flatten(_.map(others, function(other){return _.where(users, other);}));
您可以索引其他索引,然后无需嵌套循环即可获得所需的结果。应该是比较高效的方案,不管数据量有多大:
// 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;
});
这给出了相同的结果:
[
{ 'user': 'fred', 'age': 60, 'active': false },
{ 'user': 'fred', 'age': 70, 'active': false },
{ 'user': 'fred', 'age': 22, 'active': false }
];
有趣的是,您的原始解决方案是所有这些答案中性能最高的。
这里的性能问题可以忽略不计。大多数情况下,DOM交互是前端的主要性能瓶颈。如果你要 运行 针对巨大的数据集并注意到锁定,你肯定想通过使用 for 循环而不是使用 lodash 函数迭代来进一步优化它......但你通常不会遇到那个JavaScript...SQL 中的数据类型,其他人会更好地处理它。
使用 ES6 fat arrows 和 lodash 的拒绝:
const result = _.reject(users, (item) => _.find(others, { user: item.user }));
如果您使用的是 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;
})
此问题特定于 lodash。
给定两个对象数组,用另一个数组的对象过滤一个数组的最佳方法是什么?我试图在下面提出一个场景,我这样做的方法是使用两个 .forEach
循环,但我想知道使用 lodash 是否有更好的方法来处理这种类型的过滤.
例子
对象的主要源数组是
users
.
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 }
];
将过滤 users
数组的对象数组称为 others
。
var others = [
{ 'user': 'fred', 'age': 60 },
{ 'user': 'fred', 'age': 70},
{ 'user': 'fred', 'age': 22}
];
基于others
过滤users
的期望结果是:
[
{ 'user': 'fred', 'age': 60, 'active': false },
{ 'user': 'fred', 'age': 70, 'active': false },
{ 'user': 'fred', 'age': 22, 'active': false }
];
这是获得所需结果的一种方法。
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);
这里是jsbin上的例子。
http://jsbin.com/hapariviya/1/edit?html,js,console,output
这是我能想到的更简洁的方法:
var result = _.flatten(_.map(others, function(item){
return _.filter(users, item);
}));
编辑: 抱歉 JS Bin 输出混淆了嵌套数组。
var result = _.flatten(_.map(others, function(other){return _.where(users, other);}));
您可以索引其他索引,然后无需嵌套循环即可获得所需的结果。应该是比较高效的方案,不管数据量有多大:
// 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;
});
这给出了相同的结果:
[
{ 'user': 'fred', 'age': 60, 'active': false },
{ 'user': 'fred', 'age': 70, 'active': false },
{ 'user': 'fred', 'age': 22, 'active': false }
];
有趣的是,您的原始解决方案是所有这些答案中性能最高的。
这里的性能问题可以忽略不计。大多数情况下,DOM交互是前端的主要性能瓶颈。如果你要 运行 针对巨大的数据集并注意到锁定,你肯定想通过使用 for 循环而不是使用 lodash 函数迭代来进一步优化它......但你通常不会遇到那个JavaScript...SQL 中的数据类型,其他人会更好地处理它。
使用 ES6 fat arrows 和 lodash 的拒绝:
const result = _.reject(users, (item) => _.find(others, { user: item.user }));
如果您使用的是 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;
})