不使用javascript中的filter方法如何进行过滤?

How to filter without using the filter method in javascript?

我必须将 2 个函数都使用过滤方法转换为使用 for 循环的函数,我应该怎么做?对于某些情况,它是有道理的,但是使用 push 方法有点混乱。

提前致谢

第一个函数:

function filterWithInputValue(recipes) {
    filteredRecipes = recipes.filter(recipe => {
        const lowerCaseName = recipe.name.toLowerCase().includes(input.value.toLowerCase());
        const lowerCaseDescription = recipe.description.toLowerCase().includes(input.value.toLowerCase());
        const lowerCaseIngredients = recipe.ingredients.filter(({ ingredient }) => ingredient.toLowerCase().includes(input.value.toLowerCase())).length > 0
        return  lowerCaseIngredients | lowerCaseName | lowerCaseDescription;
    });
};

我当前的函数版本:

function filterWithInputValue(recipes) {
    for (let recipe of recipes) {
        const lowerCaseName = recipe.name.toLowerCase().includes(input.value.toLowerCase());
        const lowerCaseDescription = recipe.description.toLowerCase().includes(input.value.toLowerCase());
        
        for (let ingredient of recipe.ingredients) {
            //????
        }
        
        if (lowerCaseName | lowerCaseDescription | lowerCaseIngredient) {
            filteredRecipes.push(recipe)
        };
    };
};

第二个函数:

                if(tags.length >= 1) {
                    if(input.value.length >= 3) filterWithInputValue(recipes)
                    else filteredRecipes = recipes

                    const tagList = document.querySelectorAll(".tag");
                    
                    tagList.forEach((tag) => {
                        if(tag.classList.contains("tag0")) {
                            filteredRecipes = filteredRecipes.filter(recipe => recipe.ingredients.some(
                                ({ingredient}) => ingredient.includes(tag.innerText)))
                        }
                        if(tag.classList.contains("tag1")) filteredRecipes = filteredRecipes.filter(recipe => recipe.appliance.includes(tag.innerText))
                        if(tag.classList.contains("tag2")) filteredRecipes = filteredRecipes.filter(recipe => recipe.ustensils.includes(tag.innerText))
                    })
                    createRecipeCard(filteredRecipes)
                    mainInputFiltering(filteredRecipes)
                };

recipes/data 的示例:

{
        "id": 1,
        "name" : "Limonade de Coco",
        "servings" : 1,
        "ingredients": [
            {
                "ingredient" : "Lait de coco",
                "quantity" : 400,
                "unit" : "ml"
            },
            {
                "ingredient" : "Jus de citron",
                "quantity" : 2
            },
            {
                "ingredient" : "Crème de coco",
                "quantity" : 2,
                "unit" : "cuillères à soupe"
            },
            {
                "ingredient" : "Sucre",
                "quantity" : 30,
                "unit" : "grammes"
            },
            {
                "ingredient": "Glaçons"
            }
        ],
        "time": 10,
        "description": "Mettre les glaçons à votre goût dans le blender, ajouter le lait, la crème de coco, le jus de 2 citrons et le sucre. Mixer jusqu'à avoir la consistence désirée",
        "appliance": "Blender",
        "ustensils": ["cuillère à Soupe", "verres", "presse citron" ]
    }

对于相当直接的转换,您的第一个函数可能如下所示(未测试):

function filterWithInputValue(recipes) {
  let filteredRecipes = []; // create array to hold the results of filtering the recipes

  for (let recipe of recipes) {
    const lowerCaseName = recipe.name.toLowerCase().includes(input.value.toLowerCase());
    const lowerCaseDescription = recipe.description.toLowerCase().includes(input.value.toLowerCase());

    let filteredIngredients = []; // create array to hold the results of filtering the ingredients
    for (let { ingredient } of recipe.ingredients) {
      if(ingredient.toLowerCase().includes(input.value.toLowerCase())) {
        filteredIngredients.push(ingredient); // push those that succeed on the condition into the results array
      }
    }
    
    let lowerCaseIngredient = filteredIngredients.length > 0;

    if (lowerCaseName | lowerCaseDescription | lowerCaseIngredient) {
      filteredRecipes.push(recipe); // push those that succeed on the condition into the results array
    }
  }

  return filteredRecipes; // return the results of filtering
}

这里的一般原则是您可以创建一个数组来累积结果,将在条件条件下成功的东西(您从过滤器方法中获取的)添加到这个数组,然后 return 数组。

上面的稍微干净的版本可能如下所示:

function filterIngredients(ingredients, lowercaseInput) {
  let filteredIngredients = []; // create array to hold the results of filtering the ingredients
  for (let { ingredient } of ingredients) {
    if(ingredient.toLowerCase().includes(lowercaseInput)) {
      filteredIngredients.push(ingredient); // push those that succeed on the condition into the results array
    }
  }
  return filteredIngredients;
}

function filterWithInputValue(recipes) {
  let lowercaseInput = input.value.toLowerCase();
  let filteredRecipes = []; // create array to hold the results of filtering the recipes

  for (let recipe of recipes) {
    const lowerCaseName = recipe.name.toLowerCase().includes(lowercaseInput);
    const lowerCaseDescription = recipe.description.toLowerCase().includes(lowercaseInput);

    const lowerCaseIngredient = filteredIngredients(recipe.ingredients, lowercaseInput).length > 0;

    if (lowerCaseName | lowerCaseDescription | lowerCaseIngredient) {
      filteredRecipes.push(recipe); // push those that succeed on the condition into the results array
    }
  }

  return filteredRecipes; // return the results of filtering
}

您可能会在此处看到成分过滤遵循与食谱过滤相同的一般模式。

一些注意事项:

  1. 看起来成分过滤器实际上可能是 some 而不是因为它看起来只是检查成分是否匹配,并不关心它们的数量或细节。
  2. 原来的 filterWithInputValue 实际上 return 什么都没有,所以我想知道它是如何被使用/检查的。