【问题标题】:How to filter multi-condition with Lodash _.filter?如何使用 Lodash _.filter 过滤多条件?
【发布时间】:2018-09-02 01:53:16
【问题描述】:

我想从集合中过滤两个obj,conditionArr从Server获取,所以不可预知。

我的代码是:

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 })),
}))

谢谢...

【问题讨论】:

    标签: javascript filter lodash


    【解决方案1】:

    使用_.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 过滤第一个数组。

    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 - 我在答案中添加了一个 ES6 intersectionBy
    • 酷!实际上我也不能使用 ES6 ???。无论如何,我会试一试...在转换为 ES5 之后
    【解决方案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>

    【讨论】:

      【解决方案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}
      

      【讨论】:

        【解决方案4】:

        _.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>

        【讨论】:

          【解决方案5】:

          如果您必须使用 lodash 来实现这一点,您可以使用与 array.filter 相同的方式进行操作

          _.filter(users, ({user}) => user === 'barney' || user === 'fred');
          

          【讨论】:

            【解决方案6】:

            只需使用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);

            【讨论】:

              猜你喜欢
              • 2019-01-22
              • 2021-11-29
              • 2018-05-30
              • 2018-10-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-11-29
              相关资源
              最近更新 更多