Reputation: 13
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
},
]
Upvotes: 0
Views: 842
Reputation: 313
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);
Upvotes: 0
Reputation: 155892
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);
Upvotes: 1
Reputation: 169
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
Upvotes: 0