Nodejs Express - Is there any way to reduce the following code to something simpler?

Viewed 65

I have the following code that I would like to reduce. This question might be very lame, so sorry about it. I wanted to replace the meal1..10 with a variable in a for loop, but I'm not sure if that can be done in node js.

function hasPortion(meals) {
const portions = ["4", "3", "2", "1", "1/8", "1/4", "1/2"];
if (meals.meal1 != undefined && meals.meal1.activado == "on" && portions.indexOf(meals.meal1.porcion) < 0) { return false; }
if (meals.meal2 != undefined && meals.meal2.activado == "on" && portions.indexOf(meals.meal2.porcion) < 0) { return false; }
if (meals.meal3 != undefined && meals.meal3.activado == "on" && portions.indexOf(meals.meal3.porcion) < 0) { return false; }
if (meals.meal4 != undefined && meals.meal4.activado == "on" && portions.indexOf(meals.meal4.porcion) < 0) { return false; }
if (meals.meal5 != undefined && meals.meal5.activado == "on" && portions.indexOf(meals.meal5.porcion) < 0) { return false; }
if (meals.meal6 != undefined && meals.meal6.activado == "on" && portions.indexOf(meals.meal6.porcion) < 0) { return false; }
if (meals.meal7 != undefined && meals.meal7.activado == "on" && portions.indexOf(meals.meal7.porcion) < 0) { return false; }
if (meals.meal8 != undefined && meals.meal8.activado == "on" && portions.indexOf(meals.meal8.porcion) < 0) { return false; }
if (meals.meal9 != undefined && meals.meal9.activado == "on" && portions.indexOf(meals.meal9.porcion) < 0) { return false; }
if (meals.meal10 != undefined && meals.meal10.activado == "on" && portions.indexOf(meals.meal10.porcion) < 0) { return false; } 
return true;

}

1 Answers

If meals only have these 10 properties, you may like this,

function hasPortion(meals) {
    const portions = ["4", "3", "2", "1", "1/8", "1/4", "1/2"];
    for (const prop in meals) {
        const meal = meals[prop];
        if (meal != undefined && meal.activado == "on" && portions.indexOf(meal.porcion) < 0) {
            return false;
        }
    }
    return true;
}

If you have more properties, but only want to check these 10 properties, you may like this,

function hasPortion(meals) {
    const portions = ["4", "3", "2", "1", "1/8", "1/4", "1/2"];
    for (let i = 1; i <= 10; i++) {
        const prop = `meal${i}`;
        const meal = meals[prop];
        if (meal != undefined && meal.activado == "on" && portions.indexOf(meal.porcion) < 0) {
            return false;
        }
    }
    return true;
}

Append: new solution

As we mentioned, you should use an Array to store all meal items, also you may use a Set to store portions because searching in Set is faster than Array.

const meals = [
    { activado: "on", porcion: "4" },
    { activado: "on", porcion: "1/8" },
    { activado: "on", porcion: "3" },
    { activado: "on", porcion: "1/2" },
];

function hasPortion(meals) {
    const portions = new Set(["4", "3", "2", "1", "1/8", "1/4", "1/2"]);
    return !meals.some((meal) => meal.activado === "on" && !portions.has(meal.porcion));
}

// Good case
console.log(hasPortion(meals));                // Output: true
// Add bad item
meals.push({ activado: "on", porcion: "1/3" })
console.log(hasPortion(meals));                // Output: false

Related