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
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.
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
}
Let's say that you have a car item that has 3 properties :
Now you want all of the following values to be true
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))
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.