Value of typeOfFilters is selected from different component, so in my current component I get value of currency and frequency, but my filter function doesn't iterate over frequency.
I want to add more filters to my filter function. Do tell me how can i simplify this problem? plans looks like this.
let plans = [
{
"amount": 6000,
"currency": "USD",
"frequency": "MONTH",
"planId": "plan_L7mrzVML9o6G5c",
"planName": "computer",
"provider": "stripe"
},
{
"amount": 2000,
"currency": "INR",
"frequency": "DAY",
"planId": "plan_KkHkJPEVR7ZA2s",
"planName": "Platinum",
"provider": "stripe"
}
]
const typeOfFilters = {
currency: ['INR'],
frequency: ['DAY'],
provider: "",
amount: "",
status: "",
}
const sortedTableArray = plans.filter(function (plan) {
for (const [f, values] of Object.entries(typeOfFilters)) {
if (!typeOfFilters[f]) {
return true;
}
if (
f === "currency" &&
typeOfFilters["frequency"].indexOf(plan[f]) > -1
) {
return true;
}
if (f === "currency" && typeOfFilters[f].indexOf(plan[f]) > -1) {
return true;
}
if (plan[f] === undefined || plan[f] !== typeOfFilters[f]) {
return false;
}
}
});
```
expected output should return the table entry which has the frequency inside typeOfFilter['frequency']
CodePudding user response:
I am not entirely sure what you are trying to accomplish here, but the iteration does not fail. It is just interrupted by your last check:
if (plan[f] === undefined || plan[f] !== typeOfFilters[f]) {
return false;
}
More specifically by:
plan[f] !== typeOfFilters[f]
The first filter that is checked is this one:
currency: ['INR']
And plan[f] might be 'INR', but it is not ['INR']. So this check will always fail. Therefore the filter returns false and it moves on to the next plan.
What I believe you might be after is something like this:
const plans = [
{
amount: 6000,
currency: "USD",
frequency: "MONTH",
planId: "plan_L7mrzVML9o6G5c",
planName: "computer",
provider: "stripe",
},
{
amount: 2000,
currency: "INR",
frequency: "DAY",
planId: "plan_KkHkJPEVR7ZA2s",
planName: "Platinum",
provider: "stripe",
},
];
const typeOfFilters = {
currency: ['INR'],
frequency: ['DAY'],
provider: "",
amount: "",
status: "",
};
const sortedTableArray = plans.filter(plan => {
for (const [f, value] of Object.entries(typeOfFilters)) {
if (value) {
if (Array.isArray(value) && value.includes(plan[f])) {
return true;
} else if (plan[f] === value) {
return true;
}
}
}
});
console.log(sortedTableArray);
CodePudding user response:
let plans = [
{
"amount": 6000,
"currency": "USD",
"frequency": "MONTH",
"planId": "plan_L7mrzVML9o6G5c",
"planName": "computer",
"provider": "stripe"
},
{
"amount": 2000,
"currency": "INR",
"frequency": "DAY",
"planId": "plan_KkHkJPEVR7ZA2s",
"planName": "Platinum",
"provider": "stripe"
}
]
let plansWithId = plans.map((item)=>{
item.id = guidGenerator();
return item;
});
const typeOfFilters = {
currency: ['INR'],
frequency: ['MONTH'],
provider: "",
amount: "",
status: "",
}
// 1. let your typeOfFilters have values are array. If not use typeof to make sure all are in same format.
//2. add a id value to your plans to avoid duplicates
let output = [];
for(key in typeOfFilters){
let toff = typeOfFilters[key];
if(typeof(toff) === 'string'){
toff = [toff];
}
const onlyvalues = toff.filter(v => v); // filter empty values
if(onlyvalues.length){
temp = plansWithId.filter((item) => {
return onlyvalues.indexOf(item[key]) !== -1;
});
output = output.concat(temp);
}
}
const selectedIds = [];
const duplicatesRemoved = output.filter((item) => {
if(selectedIds.indexOf(item.id) !== -1){
return false;
}
selectedIds.push(item.id);
return true;
})
console.log(duplicatesRemoved)
function guidGenerator() {
var S4 = function() {
return (((1 Math.random())*0x10000)|0).toString(16).substring(1);
};
return (S4() S4() "-" S4() "-" S4() "-" S4() "-" S4() S4() S4());
}
The approach is difference in this solution. The typeOfFilters are looped first and if it matches with any in plans, the output will be generated.
Note: This is based on OR condition. so any filter matches, it will provide the output.