Search code examples
javascriptecmascript-6lodash

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?

I also tried lodash

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

doesn't work as expected?


Solution

  • With lodash, you can use _.reject() with _.isEmpty() to remove items that have an empty value object and an empty options array:

    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:

    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>