lodash:使用不同的对象数组过滤对象数组

时间:2015-04-30 21:39:08

标签: javascript arrays lodash

此问题仅适用于 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

4 个答案:

答案 0 :(得分:8)

这是我能想到的清洁方式:

var result = _.flatten(_.map(others, function(item){
  return _.filter(users, item);
}));

编辑: 道歉 JS Bin 输出混淆了嵌套数组。

答案 1 :(得分:6)

您可以索引其他人,然后在不必嵌套循环的情况下获得所需的结果。无论数据量多少,它都应该是一个相对有效的解决方案:

// 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 }
];

有趣的是,您的原始解决方案是所有这些答案中最高效的解决方案。

http://jsperf.com/testingdiwq

这里的性能问题几乎可以忽略不计。在大多数情况下,DOM交互是前端的主要性能瓶颈。如果你是针对庞大的数据集运行它并注意到锁定,你肯定希望通过使用for循环而不是使用lodash函数进行迭代来进一步优化它....但是你通常不会遇到这种类型的数据JavaScript ...... SQL和其他人会更好地处理它。

答案 2 :(得分:3)

使用ES6胖箭和lodash的拒绝:

const result = _.reject(users, (item) => _.find(others, { user: item.user }));

答案 3 :(得分:0)

如果您使用lodash和ES6语法。

public class TestContext : DbContext
{
 public CCPGV1Context(string connectionString):base(connectionString)
    {

    }

protected override void OnModelCreating(ModelBuilder modelBuilder)
    {

        base.OnModelCreating(modelBuilder);
    }
}