Last active
February 23, 2024 12:59
-
-
Save jherax/f11d669ba286f21b7a2dcff69621eb72 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 using 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]); | |
}); | |
}); | |
} | |
/** | |
* The method `filterArray()` has the following signature: | |
* | |
* `function filterArray<TInput = any>(array: TInput[], filters: IFilters) => TInput[]` | |
* | |
* Where the function receives an array as the first argument, and a plain object | |
* describing the fields to filter as the last argument. | |
* The function returns an array of the same type as the input array. | |
* | |
* The signature of the filters arguments is the following: | |
* | |
* `interface IFilters { | |
* [key: string]: (value: any) => boolean; | |
* }` | |
* | |
* Where the `filters` argument is an object that contains a `key: string` | |
* and its value is a function with the value of the property to evaluate. | |
* As the function predicate is evaluated using the `Array.prototype.every()` method, | |
* then it must return a boolean value, which will determine if the item | |
* must be included or not in the filtered array. | |
*/ |
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 filters = { | |
size: (size) => size === 50 || size === 70, | |
color: (color) => ['blue', 'black'].includes(color.toLowerCase()), | |
details: (details) => details.length < 30 && details.width >= 70, | |
locations: (locations) => { | |
if (locations.includes('USA')) return true; // case sensitive | |
if (locations.includes('Japan')) return true; // case sensitive | |
const url = window.location.pathname.toLowerCase(); | |
if (url.includes('/en-us/')) return true; // not case sensitive | |
if (url.includes('/es/')) return true; // not case sensitive | |
return false; | |
} | |
}; | |
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); | |
}); | |
}); |
I made a small lib to solve this problem
https://github.com/circa10a/filter-object-array
I have an array of Sizes which is Size = ["40","XL","43","M"]
This is what my Products JSON File looks like :
[{
"productCatgoris": "womensfashion",
"productSubCatgoris": "Kamiz",
"productStoreName": "S-trade Store",
"productId": "27",
"productName": "Cotton Unstitched Salwar Kameez for Women - Pink",
"productImage": "https://images.pexels.com/photos/15388429/pexels-photo-15388429.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
"productPrice": "699",
"productDiscount": "10",
"offerStatus": false,
"productBrand": "Strade",
"ExpressDelivary": true,
"FreeDelivary": true,
"productStock": "60",
"productSold": "10",
"offerStartAndEnDate": "12-12-2021-01-04-2022",
"offerName": "",
"productDescription": ["Cotton Unstitched Salwar Kameez for Women - Pink"],
"productSpecipication": {
"Brand": "S-trade",
"size": ["XL", "M", "L", "S", "2XL"],
"gender": "Womens",
"Color": ["Pink"]
},
"productShipping": "Dhaka city !!!! Feel free to buy from this site as we promise you same day delivery of any purchased items. Sookh helps you to purchase any goods or service with a very few steps. If you ever find any obligation of returning any purchased item or items, please review our Return & Refund Policy.",
"productReviews": []
},
{
"productCatgoris": "womensfashion",
"productSubCatgoris": "Kamiz",
"productStoreName": "S-trade Store",
"productId": "28",
"productName": "Cotton Unstitched Salwar Kameez for Women - Pink",
"productImage": "https://images.pexels.com/photos/15388429/pexels-photo-15388429.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
"productPrice": "699",
"productDiscount": "10",
"offerStatus": false,
"productBrand": "Strade",
"ExpressDelivary": false,
"FreeDelivary": false,
"productStock": "60",
"productSold": "10",
"offerStartAndEnDate": "12-12-2021-01-04-2022",
"offerName": "",
"productDescription": ["Cotton Unstitched Salwar Kameez for Women - Pink"],
"productSpecipication": {
"Brand": "S-trade",
"size": ["41", "42", "43", "45"],
"gender": "Womens",
"Color": ["Pink"]
},
"productShipping": "Dhaka city !!!! Feel free to buy from this site as we promise you same day delivery of any purchased items. Sookh helps you to purchase any goods or service with a very few steps. If you ever find any obligation of returning any purchased item or items, please review our Return & Refund Policy.",
"productReviews": []
},
{
"productCatgoris": "womensfashion",
"productSubCatgoris": "Kaftan",
"productStoreName": "S-trade Store",
"productId": "29",
"productName": "Georgette Luxury Kaftan",
"productImage": "https://images.pexels.com/photos/15388429/pexels-photo-15388429.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
"productPrice": "699",
"productDiscount": "10",
"offerStatus": false,
"productBrand": "Strade",
"ExpressDelivary": true,
"FreeDelivary": true,
"productStock": "60",
"productSold": "10",
"offerStartAndEnDate": "12-12-2021-01-04-2022",
"offerName": "",
"productDescription": ["Georgette Luxury Kaftan"],
"productSpecipication": {
"Brand": "S-trade",
"size": ["41", "42", "43", "45"],
"gender": "Womens",
"Color": ["Pink"]
},
"productShipping": "Dhaka city !!!! Feel free to buy from this site as we promise you same day delivery of any purchased items. Sookh helps you to purchase any goods or service with a very few steps. If you ever find any obligation of returning any purchased item or items, please review our Return & Refund Policy.",
"productReviews": []
},
{
"productCatgoris": "womensfashion",
"productSubCatgoris": "Kaftan",
"productStoreName": "S-trade Store",
"productId": "30",
"productName": "Georgette Luxury Kaftan",
"productImage": "https://images.pexels.com/photos/15388429/pexels-photo-15388429.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
"productPrice": "699",
"productDiscount": "10",
"offerStatus": false,
"productBrand": "Strade",
"ExpressDelivary": false,
"FreeDelivary": false,
"productStock": "60",
"productSold": "10",
"offerStartAndEnDate": "12-12-2021-01-04-2022",
"offerName": "",
"productDescription": ["Georgette Luxury Kaftan"],
"productSpecipication": {
"Brand": "S-trade",
"size": ["41", "42", "43", "45"],
"gender": "Womens",
"Color": ["Pink"]
},
"productShipping": "Dhaka city !!!! Feel free to buy from this site as we promise you same day delivery of any purchased items. Sookh helps you to purchase any goods or service with a very few steps. If you ever find any obligation of returning any purchased item or items, please review our Return & Refund Policy.",
"productReviews": []
},
{
"productCatgoris": "womensfashion",
"productSubCatgoris": "Kamiz",
"productStoreName": "S-trade Store",
"productId": "31",
"productName": "Cotton Unstitched Salwar Kameez for Women - Pink",
"productImage": "https://images.pexels.com/photos/15388429/pexels-photo-15388429.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
"productPrice": "699",
"productDiscount": "10",
"offerStatus": false,
"productBrand": "Strade",
"ExpressDelivary": false,
"FreeDelivary": false,
"productStock": "60",
"productSold": "10",
"offerStartAndEnDate": "12-12-2021-01-04-2022",
"offerName": "",
"productDescription": ["Cotton Unstitched Salwar Kameez for Women - Pink"],
"productSpecipication": {
"Brand": "S-trade",
"size": ["40", "41", "42", "43", "45"],
"gender": "Womens",
"Color": ["Pink"]
},
"productShipping": "Dhaka city !!!! Feel free to buy from this site as we promise you same day delivery of any purchased items. Sookh helps you to purchase any goods or service with a very few steps. If you ever find any obligation of returning any purchased item or items, please review our Return & Refund Policy.",
"productReviews": []
},
]
I have to find all products based on a given size array. That size needs to match the productSpecipication > Size[]
array. if matched, it will return the particular products as a products array.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great code!
@estherjsuh where you able to solve it? I have the same problem....