'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 |
