I know this question has been asked before, but existing solutions do not seem to work for my case. I am trying to filter out data on the basis of multiple properties/values in a varied array of objects.
My sample data looks like this:
const products = [
{ name: 'A', color: 'Blue', size: 50, locations: 'USA' },
{ name: 'B', color: 'Blue', size: 60, locations: 'Europe' },
{ name: 'C', color: 'Blue', size: 30, locations: 'Europe' },
{ name: 'D', color: 'Black', size: 70, locations: 'Japan' },
{ name: 'E', color: 'Green', size: 50, locations: 'Europe' },
{ name: 'F', color: 'Blue', size: 50, locations: 'Brazil' },
{ name: 'G', color: 'Black', size: 40, locations: 'Australia' },
];
This is what I require the filters result to be:
const filters_one = ['Blue'];
const requiredResult_One = [
{ name: 'A', color: 'Blue', size: 50, locations: 'USA' },
{ name: 'B', color: 'Blue', size: 60, locations: 'Europe' },
{ name: 'C', color: 'Blue', size: 30, locations: 'Europe' },
{ name: 'E', color: 'Blue', size: 50, locations: 'Brazil' },
]
const filters_two = ['Blue', 'Europe'];
const requiredResult_Two = [
{ name: 'B', color: 'Blue', size: 60, locations: 'Europe' },
{ name: 'C', color: 'Blue', size: 30, locations: 'Europe' },
]
----------OR-------------------------
const filters_three = ['Black'];
const requiredResult_three = [
{ name: 'D', color: 'Black', size: 70, locations: 'Japan' },
{ name: 'G', color: 'Black', size: 40, locations: 'Australia' },
]
const filters_four = ['Black', 'Japan'];
const requiredResult_Four = [
{ name: 'D', color: 'Black', size: 70, locations: 'Japan' },
]
this is what I have achieved so far:
const filterdata = (products, filter) => {
// where, filter can be equal to *filters_one*, *filters_two*, *filters_three*,
or *filters_four* anyone of it. //
const keysExact = ['color', 'locations'];
const valuesExact = filter.map(col => col.toLowerCase());
const resultExact = products.filter((prod) =>
keysExact.every((key) => valuesExact.includes(prod[key].toLowerCase()))
);
console.log(resultExact);
};
This seems to work partially or not looks like a good approach to me. If anyone can help me with a way better solution on this, will be really helpful.
Thanks in advance!
CodePudding user response:
You could get the values from the object and check if all values of the query is in the values array.
const
filter = (data, query) => data.filter(o => {
const values = Object.values(o);
return query.every(q => values.includes(q));
}),
products = [{ name: 'A', color: 'Blue', size: 50, locations: 'USA' }, { name: 'B', color: 'Blue', size: 60, locations: 'Europe' }, { name: 'C', color: 'Blue', size: 30, locations: 'Europe' }, { name: 'D', color: 'Black', size: 70, locations: 'Japan' }, { name: 'E', color: 'Green', size: 50, locations: 'Europe' }, { name: 'F', color: 'Blue', size: 50, locations: 'Brazil' }, { name: 'G', color: 'Black', size: 40, locations: 'Australia' }];
console.log(filter(products, ['Blue']));
console.log(filter(products, ['Blue', 'Europe']));
console.log(filter(products, ['Black']));
console.log(filter(products, ['Black', 'Japan']));
.as-console-wrapper { max-height: 100% !important; top: 0; }
CodePudding user response:
You can create a filter based on color
and location
const products = [
{ name: 'A', color: 'Blue', size: 50, locations: 'USA' },
{ name: 'B', color: 'Blue', size: 60, locations: 'Europe' },
{ name: 'C', color: 'Blue', size: 30, locations: 'Europe' },
{ name: 'D', color: 'Black', size: 70, locations: 'Japan' },
{ name: 'E', color: 'Green', size: 50, locations: 'Europe' },
{ name: 'F', color: 'Blue', size: 50, locations: 'Brazil' },
{ name: 'G', color: 'Black', size: 40, locations: 'Australia' },
];
function filterProducts(filterParams) {
const [color, country] = filterParams;
const output = products.filter((product) => product.color === color && (country ? product.locations === country : true))
return output;
}
const filters_one = ['Blue'];
const requiredResult_One = filterProducts(filters_one);
console.log(requiredResult_One);
const filters_two = ['Blue', 'Europe'];
const requiredResult_Two = filterProducts(filters_two);
console.log(requiredResult_Two);
const filters_three = ['Black'];
const requiredResult_three = filterProducts(filters_three);
console.log(requiredResult_three);
const filters_four = ['Black', 'Japan'];
const requiredResult_Four = filterProducts(filters_four);
console.log(requiredResult_Four);
CodePudding user response:
const filterArray = (filter, arr) => {
return arr.filter(val => (filter[1]
? val.color === filter[0] && val.locations === filter[1]
: val.color === filter[0]));
};
CodePudding user response:
You can use an object to filter list:
let products = [{ name: 'A', color: 'Blue', size: 50, locations: 'USA' }, { name: 'B', color: 'Blue', size: 60, locations: 'Europe' }, { name: 'C', color: 'Blue', size: 30, locations: 'Europe' }, { name: 'D', color: 'Black', size: 70, locations: 'Japan' }, { name: 'E', color: 'Green', size: 50, locations: 'Europe' }, { name: 'F', color: 'Blue', size: 50, locations: 'Brazil' }, { name: 'G', color: 'Black', size: 40, locations: 'Australia' },];
function* filter(array, list = {}) {
loop: for (let item of array) {
for (let [k, v] of Object.entries(list))
if (item[k] != v)
continue loop;
yield item;
}
}
console.log("size:50", [...filter(products, { size: 50 })])
console.log("color:Blue", [...filter(products, { color: 'Blue' })])
console.log("color:Blue, size:50", [...filter(products, { color: 'Blue', size: 50 })])
console.log("color:Blue, locations:Europe", [...filter(products, { color: 'Blue', locations: 'Europe' })])
This example is very fast, flexible and lazy!