Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript Filter OR AND together

Tags:

javascript

I have an array of objects that I need to filter from another object, which contains the same keys, where the values ​​are arrays. I need it to be considered OR within the same filter array, but if they are different filters, it must be considered AND.

The size of the objects is variable, it can contain 2 or 30 items, so we cannot mention the keys explicitly.

Ex:

#data
[
    {a:'1',b:'2'},
    {a:'3',b:'4'},
    {a:'5',b:'6'}
]

#filter 1
{a:['1','3']}

#result 1
[
    {a:'1',b:'2'},
    {a:'3',b:'4'},
]

#filter 2
{a:['1','3'],b:['2']}

#result 2
[
    {a:'1',b:'2'}
]

I tried to use this code, but the result was not what I expected, it returned everything with OR.

return this.data.filter(
    (objData:any) => {
        return Object.keys(currDataRow).some(
            (keyDataRow:any) => {                       
                if(typeof(objFilter[keyDataRow])!=='undefined') {
                return objFilter[keyDataRow].includes(currDataRow[keyDataRow])                          
            }
                return false;
            }
        )   
    }
)

Then I tried this other result, it improved, but it is still not the expected result because selecting two of the same filter did not return correctly

return this.data.filter(
   (objData:any) => {
        let result = 0;
        let countFilter = 0;
        Object.keys(currDataRow).some(
            (keyDataRow:any) => {                                               
            if(typeof(objFilter[keyDataRow])!=='undefined') {                           
                countFilter += objFilter[keyDataRow].length
            result += objFilter[keyDataRow].includes(currDataRow[keyDataRow]) ? 1 : 0;                          
        }
        }
        )               
        return result == countFilter;
    }
)
like image 340
Pablo Souza Avatar asked Apr 30 '26 08:04

Pablo Souza


1 Answers

It will be easier if you iterate the filter key/value pairs and require that every pair of them has a match for the current object:

const applyFilter = (data, filter) => data.filter(obj => 
    Object.entries(filter).every(([key, values]) =>
        values.includes(obj[key])
    )
);

// Example run
const data = [
    { a: '1', b: '2' },
    { a: '3', b: '4' },
    { a: '5', b: '6' }
];
const filter2 = { a: ['1', '3'], b: ['2'] };
const result = applyFilter(data, filter2);
console.log(result);
like image 150
trincot Avatar answered May 02 '26 20:05

trincot



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!