0

I have result type of object. I want to filter the records from the result obj. I have 3 filters in my form (Search by name, city, email). All filters are multi-select. Now I want to filter my result records by the above filters array.

User filtered by records using below array

var searchByname = ['john', 'test1'];
var searchByEmail = ['[email protected]', '[email protected]'];
var searchByCity = ['CA', 'LA'];

Actual result object from where the filter should be done

var result = [
    {
        'name': 'john',
        'email': '[email protected]',
        'city': 'CA',
        'phone': 425663313
    },
    {
        'name': 'test1',
        'email': '[email protected]',
        'city': 'LA',
        'phone': 7418669633
    },
    {
        'name': 'Dyna',
        'email': '[email protected]',
        'city': 'New York',
        'phone': 12345666
    }
]

I tried below solution but it filter only any one filter records

var filteredArray_1 = result.filter(function(itm){
    return searchByname.indexOf(itm.name) > -1;
});
var filteredArray_2 = result.filter(function(itm){
    return searchByEmail.indexOf(itm.email) > -1;
});
var filteredArray_3 = result.filter(function(itm){
    return searchByCity.indexOf(itm.city) > -1;
});
let finalArray = [...filteredArray_1, ...filteredArray_2, ...filteredArray_3];

Expected Output

var result = [
    {
        'name': 'john',
        'email': '[email protected]',
        'city': 'CA',
        'phone': 425663313
    },
    {
        'name': 'test1',
        'email': '[email protected]',
        'city': 'LA',
        'phone': 7418669633
    },
]

3 Answers 3

1

Your filter includes results from any passing filter and can include results twice.

Instead apply all your filters together:

const searchByname = ['john', 'test1'];
const searchByEmail = ['[email protected]', '[email protected]'];
const searchByCity = ['CA', 'LA'];

const result = [
    {
        'name': 'john',
        'email': '[email protected]',
        'city': 'CA',
        'phone': 425663313
    },
    {
        'name': 'test1',
        'email': '[email protected]',
        'city': 'LA',
        'phone': 7418669633
    },
    {
        'name': 'Dyna',
        'email': '[email protected]',
        'city': 'New York',
        'phone': 12345666
    }, 
    undefined, // Dummy test empty
    { } // Dummy test with no properties
];

const multifiltered = result.
    filter(itm => searchByname.indexOf(itm?.name) > -1).
    filter(itm => searchByEmail.indexOf(itm?.email) > -1).
    filter(itm => searchByCity.indexOf(itm?.city) > -1);
    
console.log('Multiple filters', multifiltered);

// However, your code will be easier to read if you do a single operation...

const filteredAND = result.
    filter(itm => 
        itm &&
        searchByname.indexOf(itm.name) > -1 &&
        searchByEmail.indexOf(itm.email) > -1 &&
        searchByCity.indexOf(itm.city) > -1);
        
console.log('AND filters', filteredAND);

const filteredOR = result.
    filter(itm => 
        itm && (
        searchByname.indexOf(itm.name) > -1 ||
        searchByEmail.indexOf(itm.email) > -1 ||
        searchByCity.indexOf(itm.city) > -1));
        
console.log('OR filters', filteredOR);

Sign up to request clarification or add additional context in comments.

5 Comments

Is it giving me result if one of my filter is null?
@UserPHP No, but its easy to add item && (...) around the clause
I am not getting can add it into the current code
@UserPHP snippet updated with null checks
From my 3 filters if only searchByname has value but other two has not any value they both are empty is it works?
0

I am not sure if I understand your question fully.

but you could filter in this manner

var filtered = result.filter(
  (item) =>
    searchByname.includes(item.name) ||
    searchByEmail.includes(item.email) ||
    searchByCity.includes(item.city)
);

This would give you the desired result

Comments

0

You can try any of this based on your requirement,

let andFiltered = result.filter(
  (data) =>
    searchByname.includes(data.name) &&
    searchByEmail.includes(data.email) &&
    searchByCity.includes(data.city)
);

console.log(andFiltered);

let orFiltered = result.filter(
  (data) =>
    searchByname.includes(data.name) ||
    searchByEmail.includes(data.email) ||
    searchByCity.includes(data.city)
);

console.log(orFiltered);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.