-
-
Save secretgspot/071c7899abe875effa568cff0a6d91bd to your computer and use it in GitHub Desktop.
Filters an array of objects with multiple match-criteria.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Filters an array of objects by custom predicates. | |
* | |
* @param {Array} array: the array to filter | |
* @param {Object} filters: an object with the filter criteria | |
* @return {Array} | |
*/ | |
function filterArray(array, filters) { | |
const filterKeys = Object.keys(filters); | |
return array.filter(item => { | |
// validates all filter criteria | |
return filterKeys.every(key => { | |
// ignores non-function predicates | |
if (typeof filters[key] !== 'function') return true; | |
return filters[key](item[key]); | |
}); | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe('Testing filterArray()', () => { | |
it('should filter an array of objects by custom predicates', () => { | |
const products = [ | |
{ name: 'A', color: 'Blue', size: 50, locations: ['USA', 'Europe'], details: { length: 20, width: 70 } }, | |
{ name: 'B', color: 'Blue', size: 60, locations: [], details: { length: 20, width: 70 } }, | |
{ name: 'C', color: 'Black', size: 70, locations: ['Japan'], details: { length: 20, width: 71 } }, | |
{ name: 'D', color: 'Green', size: 50, locations: ['USA'], details: { length: 20, width: 71 } }, | |
]; | |
const filters = { | |
size: size => size === 50 || size === 70, | |
color: color => ['blue', 'black'].includes(color.toLowerCase()), | |
locations: locations => locations.find(x => ['JAPAN', 'USA'].includes(x.toUpperCase())), | |
details: details => details.length < 30 && details.width >= 70, | |
}; | |
const filtered = filterArray(products, filters); | |
const expected = [ | |
{ name: 'A', color: 'Blue', size: 50, locations: ['USA', 'Europe'], details: { length: 20, width: 70 } }, | |
{ name: 'C', color: 'Black', size: 70, locations: ['Japan'], details: { length: 20, width: 71 } }, | |
]; | |
expect(filtered).toStrictEqual(expected); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ignores case-sensitive | |
const getValue = value => (typeof value === 'string' ? value.toUpperCase() : value); | |
/** | |
* Filters an array of objects (one level-depth) with multiple criteria. | |
* | |
* @param {Array} array: the array to filter | |
* @param {Object} filters: an object with the filter criteria | |
* @return {Array} | |
*/ | |
function filterPlainArray(array, filters) { | |
const filterKeys = Object.keys(filters); | |
return array.filter(item => { | |
// validates all filter criteria | |
return filterKeys.every(key => { | |
// ignores an empty filter | |
if (!filters[key].length) return true; | |
return filters[key].find(filter => getValue(filter) === getValue(item[key])); | |
}); | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe('Testing filterPlainArray()', () => { | |
it('should filter an array of objects with one level-depth', () => { | |
const products = [ | |
{ name: 'A', color: 'Blue', size: 50 }, | |
{ name: 'B', color: 'Blue', size: 60 }, | |
{ name: 'C', color: 'Black', size: 70 }, | |
{ name: 'D', color: 'Green', size: 50 }, | |
]; | |
const filters = { | |
color: ['BLUE', 'black'], | |
size: [70, 50], | |
}; | |
const filtered = filterPlainArray(products, filters); | |
const expected = [ | |
{ name: 'A', color: 'Blue', size: 50 }, | |
{ name: 'C', color: 'Black', size: 70 }, | |
]; | |
expect(filtered).toStrictEqual(expected); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment