简体   繁体   English

在多条件下过滤对象数组

[英]filter array of object on multi conditions

I have this array我有这个数组

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

I want to filter if value doesn't have a value or options is an empty array.如果值没有值或选项是空数组,我想过滤。 So I did所以我做了

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

I expect type:name is gone but why it's still there?我希望type:name消失了,但为什么它仍然存在?

I also tried lodash我也试过 lodash

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

doesn't work as expected?没有按预期工作?

{} and [] are truthy values {}[]是真实值

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

You can check for length in case of array, in case of object you can get keys or values or entries and check it's length 您可以检查数组的长度,如果是对象,则可以获取键,值或条目并检查其长度

 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) 

{} is still a truthy value, you must check for its keys' length {}仍然是真实值,您必须检查其键的长度

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

Here is my solution. 这是我的解决方案。

 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))); 

Hope will help you. 希望会对您有所帮助。

Give the custom filter callback where you check for any entry in values property and options property. 提供自定义过滤器回调,您可以在其中检查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); 

With lodash, you can use _.reject() with _.isEmpty() to remove items that have an empty value object and an empty options array: 使用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> 

With lodash/fp you can easily generate a function that extracts the value and the options , iterates them with _.every() and return true (should be removed) if both are empty: 使用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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM