Home > Net >  Filter array of objects based on another object
Filter array of objects based on another object

Time:02-24

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.

  • Related