I have been stuck on this for an entire day and still nowhere near achieving this.
I have a product with fields as follow
products :[
{
brand :"Ray Band",
size :"medium",
price :250,
...others
},
{
brand :"Okaley",
size :"large",
price :500,
...others
},
{
brand :"Dior",
size :"free size",
price :475,
...others
}
]
I want to filter these products by providing certain fields. I want to filter them by using an object below.
const filterFields ={
brand :["rayband","okaley"],
size :["free size"]
}
I want to filter the products by "brand" "ray band" or "okaley". Also their sizes will have to be "free size". I also want to add other keys and values dynamically by displaying checkbox. I also expect them to work properly without having to check if else manually. How do I do that? I have tried a lot of different ways and nothing so far have worked since it includes a lot of nested forEachs. Please someone help me here. I am also using React.js
CodePudding user response:
This way should work dynamically for any key name
const filtered = products.filter(product => {
return Object.keys(filterFields).reduce((acc, filter) => {
const filterValues = filterFields[filter];
const productValue = product[filter];
//This line defines what is your match
const found = filterValues.find(fv => fv == productValue);
return acc && found;
}, true);
})
You should change the inner find as you want
CodePudding user response:
Hello please try this.
const list = [
{
brand: "Ray Band",
size: "medium",
price: 250,
},
{
brand: "Okaley",
size: "large",
price: 500,
},
{
brand: "Dior",
size: "free size",
price: 475,
},
];
const filterFields = {
brand: [],
size: [],
};
list.forEach((l, index) => {
if (!filterFields.brand.find((b) => b === l.brand)) {
filterFields.brand.push(l.brand);
}
if (!filterFields.size.find((s) => s === l.size)) {
filterFields.size.push(l.size);
}
// USING DYNAMIC KEYS
let elementKeys = Object.keys(l);
elementKeys.forEach((k) => {
if (!filterFields[k]) {
filterFields[k] = [];
}
if (!filterFields[k].find((field) => field === l[k])) {
filterFields[k].push(l[k]);
}
});
});
console.log("filterFields", filterFields);
CodePudding user response:
You can use the .filter()
method in this way:
products.filter(product => filterFields.brand.includes(product.brand) || filterFields.size.includes(product.size))
This means to filter the product which it's brand name is contained in the filterField
's brand array and also same for the size