【问题标题】:How to use array filter criteria agaist object in lodash?如何在 lodash 中对对象使用数组过滤条件?
【发布时间】:2019-10-17 01:58:05
【问题描述】:

如何在lodash中过滤对象年龄与另一个对象?但条件对象是数组..

var form = { type: ['xyz', 'abc'], name: 'pre-1' }

var items = [
 { type: 'xyz', name: 'pre-1' },
 { type: 'abc', name: 'pre-1' }, 
 { type: 'xyz', name: 'pre-2' }, 
]

const results = lodash.filter(items, form);

results 应该是 xyzabc

results = [{ type: 'xyz', name: 'pre-1' }, { type: 'abc', name: 'pre-1' }]

我可以使用filter 方法吗?

【问题讨论】:

  • 您的预期输出是什么?只是 ['xyz','abc']?
  • ^^ 例如,是 OR 还是 AND。另外,您在查看the documentation 时看到了什么?
  • 我只是编辑我的问题
  • 在 lodash 文档中,他们对这样的事情只字未提

标签: javascript arrays object ecmascript-6 lodash


【解决方案1】:

好吧,您可以使用 lodash 的自定义过滤方法。试试下面:

var form = { type: ['xyz', 'abc'], name: 'pre-1' }

var items = [
 { type: 'xyz', name: 'pre-1' },
 { type: 'abc', name: 'pre-1' }, 
 { type: 'xyz', name: 'pre-2' }, 
]

let filtered = _.filter(items, (item)=>{
    return form.type.indexOf(item.type) >= 0 && form.name == item.name
});

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

【讨论】:

    【解决方案2】:
    var form = { type: ['xyz', 'abc'], name: 'pre-1' }
    
    var items = [
     { type: 'xyz', name: 'pre-1' },
     { type: 'abc', name: 'pre-1' }, 
     { type: 'xyz', name: 'pre-2' }, 
    ]
    
    var item = _.filter(items, i => {
     return form.type.indexOf(i.type) > -1 && form.name === i.name
    });
    
    console.log(item)
    

    【讨论】:

      【解决方案3】:

      检查是否form.name === item.name,如果是,则使用Array.includes() 检查item.type 是否出现在form.type 中。

      注意:我使用了 vanilla JS 过滤器并包含方法,但您可以将它们替换为 lodash 的 _.filter()_.includes()

      const form = { type: ['xyz', 'abc'], name: 'pre-1' }
      
      const items = [{"type":"xyz","name":"pre-1"},{"type":"abc","name":"pre-1"},{"type":"xyz","name":"pre-2"}]
      
      const result = items.filter(item =>
        form.name === item.name && form.type.includes(item.type)
      )
      
      console.log(result)

      lodash 的另一个选项是使用_.intersectionWith(),并在comperator 函数中检查项目的名称是否与表单的名称相同,并且类型中存在类型。

      const form = { type: ['xyz', 'abc'], name: 'pre-1' }
      
      const items = [{"type":"xyz","name":"pre-1"},{"type":"abc","name":"pre-1"},{"type":"xyz","name":"pre-2"}]
      
      const result = _.intersectionWith(items, form.type, (item, type) =>
        form.name === item.name && item.type === type
      )
      
      console.log(result)
      <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

      【讨论】:

        【解决方案4】:

        如果您将您的项目reduce 到一个对象映射,其中可以通过typename 的组合找到项目,那么它可以是key 带或不带lodash 的简单映射:

        var form = { type: ['xyz', 'abc'], name: 'pre-1' }
        
        var items = [
         { type: 'xyz', name: 'pre-1' },
         { type: 'abc', name: 'pre-1' }, 
         { type: 'xyz', name: 'pre-2' }, 
        ].reduce((r,c) => (r[`${c.type}-${c.name}`] = c, r), {}) // convert to object map
        
        let result = form.type.map(t => items[`${t}-${form.name}`]) // map by key
        
        console.log(result)

        使用 lodash,您可以使用 _.keyBy_.map

        var form = { type: ['xyz', 'abc'], name: 'pre-1' }
        
        var items = _.keyBy([
         { type: 'xyz', name: 'pre-1' },
         { type: 'abc', name: 'pre-1' }, 
         { type: 'xyz', name: 'pre-2' }, 
        ], x => `${x.type}-${x.name}`)
        
        let result = _.map(form.type, t => items[`${t}-${form.name}`])
        
        console.log(result)
        <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

        从性能的角度来看,这样您就处于O(N) 领域。

        【讨论】:

          【解决方案5】:

          纯 JS 中的简单:

          var form = { type: ['xyz', 'abc'], name: 'pre-1' }
          
          var items = [
           { type: 'xyz', name: 'pre-1' },
           { type: 'abc', name: 'pre-1' }, 
           { type: 'xyz', name: 'pre-2' }, 
          ]
          
          const res = items.filter(({ type, name }) => form.type.includes(type) && form.name == name);
          
          console.log(res);
          .as-console-wrapper { max-height: 100% !important; top: auto; }

          如果你真的想,你可以像这样使用 Lodash 的 _.filter 方法:

          var form = { type: ['xyz', 'abc'], name: 'pre-1' }
          
          var items = [
           { type: 'xyz', name: 'pre-1' },
           { type: 'abc', name: 'pre-1' }, 
           { type: 'xyz', name: 'pre-2' }, 
          ]
          
          const res = _.filter(items, ({ type, name }) => form.type.includes(type) && form.name == name);
          
          console.log(res);
          .as-console-wrapper { max-height: 100% !important; top: auto; }
          <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

          【讨论】:

            猜你喜欢
            • 2018-08-22
            • 1970-01-01
            • 2019-10-02
            • 2015-07-10
            • 2022-11-30
            • 1970-01-01
            • 2015-08-23
            • 2016-10-30
            相关资源
            最近更新 更多