【问题标题】:filter array of object on multi conditions在多个条件下过滤对象数组
【发布时间】:2019-07-03 09:45:50
【问题描述】:

我有这个数组

const d = [{
    "type": "price",
    "value": {
        "min": 0,
        "max": 170
    }
}, {
    "type": "name",
    "value": {}
}, {
    "type": "volume",
    "options": [1,2]
}]

如果 value 没有值或 options 是空数组,我想过滤。所以我做到了

d.filter(o => o.value || o.options)

我预计type:name 不见了,但为什么它仍然存在?

我也试过 lodash

d.filter(o => !isEmpty(o.value) || !isEmpty(o.options))

没有按预期工作?

【问题讨论】:

    标签: javascript ecmascript-6 lodash


    【解决方案1】:

    {}[] 是真实值

    console.log(Boolean([]))
    console.log(Boolean({}))

    您可以检查数组的长度,如果是对象,您可以获取键或值或条目并检查它的长度

    const d = [{"type": "price","value": {"min": 0,"max": 170}}, {"type": "name","value": {}}, {"type": "volume","options": [1,2]}]
    
    let op = d.filter(o => ( Object.values(o.value || {}) || (o.options || [] )).length)
    
    console.log(op)

    【讨论】:

      【解决方案2】:

      使用 lodash,您可以使用 _.reject()_.isEmpty() 来删除具有空 value 对象和空 options 数组的项目:

      const arr = [{"type": "price","value": {"min": 0,"max": 170}}, {"type": "name","value": {}}, {"type": "volume","options": [1,2]}]
      
      const result = _.reject(arr, o => _.isEmpty(o.value) && _.isEmpty(o.options))
      
      console.log(result)
      <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

      使用 lodash/fp,您可以轻松生成提取 valueoptions 的函数,使用 _.every() 迭代它们,如果两者都为空,则返回 true(应该删除):

      const { reject, flow, props, every, isEmpty } = _
      
      const fn = reject(flow(props(['value', 'options']), every(isEmpty)))
      
      const arr = [{"type": "price","value": {"min": 0,"max": 170}}, {"type": "name","value": {}}, {"type": "volume","options": [1,2]}]
      
      const result = fn(arr)
      
      console.log(result)
      <script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>

      【讨论】:

      • 如果 _.reject 与过滤器相反,为什么这不能按预期工作? arr.filter(o => !_.isEmpty(o.value) && !_.isEmpty(o.options))
      • 您只想删除 both valueoptions 的项目,但包括至少有其中一个的项目。您的条件是 - 仅当 both valueoptions 不为空时才包含。您可以将其更改为!_.isEmpty(o.value) || !_.isEmpty(o.options)!(_.isEmpty(o.value) && !_.isEmpty(o.options))
      【解决方案3】:

      这是我的解决方案。

      const d = [{
          "type": "price",
          "value": {
              "min": 0,
              "max": 170
          }
      }, {
          "type": "name",
          "value": {}
      }, {
          "type": "volume",
          "options": [1,2]
      }]
      
      function notEmpty(n){
         return (!!n ? typeof n === 'object' ? Array.isArray(n) ? !!n.length : !!Object.keys(n).length : true : false);
      }
      
      console.log(d.filter(o => notEmpty(o.value) || notEmpty(o.options)));

      希望对您有所帮助。

      【讨论】:

        【解决方案4】:

        提供自定义过滤器回调,您可以在其中检查values 属性和options 属性中的任何entry

        const d = [
        	{
        		"type": "price",
        		"value": {
        			"min": 0,
        			"max": 170
        		}
        	}, 
        	{
        		"type": "name",
        		"value": {}
        	}, 
        	{
        		"type": "volume",
        		"options": [1,2]
        	}
        ];
        
        
        function doesHaveValuesAndOptions(obj) {
        	const valueEntries = obj.value ? Object.entries(obj.value) : [],
        		    options = obj.options || [];
        	
        	if (!valueEntries.length && !options.length)
        		return false;
        	
        	else if (valueEntries.length || options.length)
        		return true;
        	
        	return false;
        }
        
        
        
        const res = d.filter(doesHaveValuesAndOptions);
        console.log(res);

        【讨论】:

          猜你喜欢
          • 2021-07-05
          • 2017-08-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-04-19
          • 2021-12-10
          • 2019-09-23
          相关资源
          最近更新 更多