Reputation: 3351
I'm writing a small js code where I need to filter the data based on key passed. Here, the main issue is, the data is not consistent(please refer to my code sample).
var users = [{
name: 'paul',
job: 'engineer'
},
{
name: 'John',
job: 'Mechanic'
},
{
name: 'paul',
job: 'Mechanic'
},
{
name: 'George',
job: 'Plumber'
},
{
name: 'John'
},
];
filtersToApply = {
job: 'engineer'
};
returnFilteredList = (users, columnDataToFilter) => {
return users.filter((row) => {
return Object.keys(columnDataToFilter).every(
(propertyName) =>
row[propertyName]
.toString()
.toLowerCase()
.indexOf(columnDataToFilter[propertyName].toString().toLowerCase()) >
-1
);
});
};
console.log(JSON.stringify(returnFilteredList(users, filtersToApply)));
Here I get the error, 'coz, there is no job
for the last JSON object in the array. how can I handle this?
Upvotes: 2
Views: 65
Reputation: 386570
You could get the entries of you filter conditions and check with Array#every
or Array#some
, depending on the need.
const
users = [{ name: 'paul', job: 'engineer' }, { name: 'John', job: 'Mechanic' }, { name: 'paul', job: 'Mechanic' }, { name: 'George', job: 'Plumber' }, { name: 'John' }],
filtersToApply = { job: 'engineer' },
filters = Object.entries(filtersToApply),
result = users.filter(user =>
filters.every(([k, v]) => (user[k] || '').toLowerCase() === v)
);
console.log(result);
If you have an array or only a sting, you need to compare each value and adjust the case in advance.
const
users = [{ name: 'paul', job: 'engineer' }, { name: 'John', job: ['Mechanic', 'Engineer'] }, { name: 'paul', job: 'Mechanic' }, { name: 'George', job: 'Plumber' }, { name: 'John' }],
filtersToApply = { job: 'engineer' },
filters = Object.entries(filtersToApply),
result = users.filter(user =>
filters.every(([k, v]) => []
.concat(user[k] || [])
.map(s => s.toLowerCase())
.includes(v)
)
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 3
Reputation: 388
return Object.keys(columnDataToFilter).every(
(propertyName) =>
row[propertyName]|| '' //you can add undefined keys to empty string.
.toString()
.toLowerCase()
.indexOf(columnDataToFilter[propertyName].toString().toLowerCase()) >
-1
);
Upvotes: 1
Reputation: 22247
Sometimes row[propertyName]
will be undefined. You can use an Optional Chaining operator to avoid the errors:
return Object.keys(columnDataToFilter).every(
(propertyName) =>
row[propertyName]? //<--
.toString()
.toLowerCase()
.indexOf(columnDataToFilter[propertyName].toString().toLowerCase()) >
-1
);
Upvotes: 1