如何使用 Lodash 的 _.filter 进行多条件筛选?

6

我希望从集合中筛选出两个对象,条件数组是从服务器获取的,因此是不可预测的。

我的代码如下:

var users = [{
        user: 'barney',
        age: 36,
        active: true
    },
    {
        user: 'fred',
        age: 40,
        active: false
    },
    {
        user: 'travis',
        age: 37,
        active: true
    }
];

// the Array fetch from Server, so it's unpredictable.
var conditionArr = [{
    user: 'barney'
}, {
    user: 'fred'
}];

// _.filter
result = _.filter(users, conditionArr);

我期望的输出:

 // expect results:
 [{
         user: 'barney',
         age: 36,
         active: true
     },
     {
         user: 'fred',
         age: 40,
         active: false
     }
 ]  

真实结果:

[]

我发现一个更好的方法:
result =  _.map(conditionArr, (con) => ({
    ...con,
   ...(_.find(users, { user: con.user })),
}))

thx...

6个回答

7

使用_.intersectionBy()函数:

const users = [{"user":"barney","age":36,"active":true},{"user":"fred","age":40,"active":false},{"user":"travis","age":37,"active":true}];

const conditionArr = [{"user":"barney"},{"user":"fred"}];

const result = _.intersectionBy(users, conditionArr, 'user');

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>

Vanilla JS - 我新增了一个简单的intersectionBy()函数,它将第二个数组中相关的key值转换成一个Set。然后你可以使用这个Set来过滤第一个数组。

const intersectionBy = (arr1, arr2, key) => {
  const keys = new Set(arr2.map(o => o[key]));
  
  return arr1.filter(o => keys.has(o[key]));
};

const users = [{"user":"barney","age":36,"active":true},{"user":"fred","age":40,"active":false},{"user":"travis","age":37,"active":true}];

const conditionArr = [{"user":"barney"},{"user":"fred"}];

const result = intersectionBy(users, conditionArr, 'user');

console.log(result);


非常酷!不幸的是,我的lodash版本太老了。但我会看看能否根据这个编写自己的函数! - Sampgun
1
@Sampgun - 我已经在答案中添加了一个 ES6 的 intersectionBy - Ori Drori
太酷了!其实我也不能使用ES6。不管怎样,我会尝试一下...在转换成ES5之后。 - Sampgun

2

只需使用array.filter:

var users = [
 { user: 'barney', age: 36, active: true },
 { user: 'fred',  age: 40, active: false },
 { user: 'travis', age: 37, active: true}
];

var result = users.filter(({user}) => user === 'barney' || user === "fred");
console.log(result);


2

像许多其他lodash函数一样,_.filter接受函数作为第二个参数(每个数组元素作为参数),如果函数返回true,则该元素保留在结果中。

var users = [
     { user: 'barney', age: 36, active: true },
     { user: 'fred', age: 40, active: false },
     { user: 'travis', age: 37, active: true }
 ];

// the Array fetch from Server, so it's unpredictable.
var conditionArr = [
  { user: 'barney'},
  { user: 'fred'}
];
 
 // Simplified condition a bit. cond = ['barney', 'fred'];
var cond = _.map(conditionArr, cond => cond.user);
 
 // _.filter
var result = _.filter(users, user => _.indexOf(cond, user.user) !== -1);

console.log('result', result);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.5/lodash.min.js"></script>


0
如果您想使用lodash来实现这个功能,可以像使用array.filter一样操作。
_.filter(users, ({user}) => user === 'barney' || user === 'fred');

-1
_.filter 方法中,你需要传递以下示例中的函数。
_.filter(users, function(o) { return !o.active; });

var users = [{
    user: 'barney',
    age: 36,
    active: true
  },
  {
    user: 'fred',
    age: 40,
    active: false
  },
  {
    user: 'travis',
    age: 37,
    active: true
  }
];


// _.filter
var result = _.filter(users, function(obj) { return obj.user=='barney'||obj.user=='fred' });

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.core.js"></script>


-3

使用原生JS,例如 -

let userSubset = users.map(function(obj, index) {

   if (obj.user === "barney" || obj.user === "fred") return obj;
}).filter(Boolean);

console.log(userSubset);

// {user: "barney", age: 36, active: true}
// {user: "fred", age: 40, active: false}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接