'How to find all combinations of if conditions by effective way?

I would like to find by effective way, because of code nesting

this.store.carsWithFilters = this.store.cars.filter(car => {
    if (price && car.price < price.value) {
        return car
    }
    if (tachometer && car.tachometer < tachometer.value) {
        return car
    }
    if (cars.length > 0 && cars.includes(car.name.split(' ')[0])) {
        return car
    }
    if (colors.length > 0 && colors.includes(car.color)) {
        return car
    }
    if (fuel && car.fuel === fuel.text) {
        return car
    }
})

turn into all possible conditions

for example I have 3 conditions

1 - if condition1
2 - if codititon2
3 - if condition3
4 - if condition1 && condition2
5 - if condition2 && condition3
6 - if condition1 && condition3
7 - if condition1 && condition2 && condition3


Solution 1:[1]

polymophism might help here. Try using a Web Framework that uses objects and classes, and try to use polymorphism to get rid of these conditionals. E. G. Try using Typescript and develop a Model that represents the relation between objects in order to use polymorphism, rather than conditionals.

Solution 2:[2]

You can factor the if using && (and)

if (price && car.price < price.value) &&
  (tachometer && car.tachometer < tachometer.value) &&
  (cars.length > 0 && cars.includes(car.name.split(' ')[0])) &&
  (colors.length > 0 && colors.includes(car.color)) &&
  (fuel && car.fuel === fuel.text)
{
  return car
}

Small example :

Let's say that you have a car item that has 3 properties :

  • NbSeats
  • Fuel
  • Color

Now you want all of the following values to be true

  • Car must have at least 5 seats
  • Car must have at lead 10 fuel
  • Car must be blue

Then you will check with the following if statement :

if(car.nbSeats > 4 && car.fuel > 10 && car.color === "blue")

If you want at least one property to be true (not all) you'll check with the || keyword

if(car.nbSeats > 4 ||  car.fuel > 10 || car.color === "blue")

const car1 = {
  nbSeats: 4,
  fuel: 20,
  color: "red"
}

const car2 = {
  nbSeats: 7,
  fuel: 5,
  color: "blue"
}

const car3 = {
  nbSeats: 6,
  fuel: 20,
  color: "blue"
}

function isCarValid(car){
  if(car.nbSeats > 4 && car.fuel > 10 && car.color === "blue") return "Valid"
  else return "Not valid"
}

console.log(isCarValid(car1))
console.log(isCarValid(car2))
console.log(isCarValid(car3))

Solution 3:[3]

If they should all truly do and return the same thing, parallel/sibling if-statements can be joined by "or"s:

if (
     (price && car.price < price.value) 
     || (tachometer && car.tachometer < tachometer.value) 
     || (cars.length > 0 && cars.includes(car.name.split(' ')[0])) 
     || (colors.length > 0 && colors.includes(car.color)) 
     || (fuel && car.fuel === fuel.text)
) {return car;}

Solution 4:[4]

Filter only needs true or false so you can return just the statements. However, if you want to ignore certain variables, you need to let undefined/null/0 to return true.

this.store.carsWithFilters = this.store.cars.filter(car => {
   (!price || car.price < price.value)
&& (!tachometer || car.tachometer < tachometer.value)
&& (cars.length == 0 || (cars.includes(car.name.split(' ')[0] || colors.includes(car.color)))
&& (!fuel || car.fuel === fuel.text)
});

This looks messy as hell, so I would use variables to make it more clean. Also, it's easier to debug if using variables.

this.store.carsWithFilters = this.store.cars.filter(car => {
  let affordable      = !price || car.price < price.value,
      milage          = !tachometer || car.tachometer < tachometer.value,
      correctCarModel = cars.length == 0 || cars.includes(car.name.split(' ')[0],
      correctCarColor = cars.length == 0 || colors.includes(car.color),
      correctFuelType = !fuel || car.fuel === fuel.text;

  return affordable && milage && (correctCarModel || correctCarColor) && correctFuelType;
});

So if you got only fuel as a variable, then affordable, milage, correctCarmodel and correctCarColor will return true.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 GabeRAMturn
Solution 2
Solution 3 user1599011
Solution 4