JS For 循环返回空数组

JS For Loops Returning Empty Array

chooseRecipe 函数应该将 bakeryAbakeryB 中的数组与每个 recipeingredients 进行比较。如果 bakeryAbakeryB 每个都有一个配方的成分,那么应该打印配方的名称。在这种情况下,Persian Cheesecake 是应该打印的内容。但是,它一直返回一个空数组。

我知道我是从一个空数组开始的,但是 suitableRecipe.push(recipes[i].name); 不应该处理这个问题吗?

如果有任何指导或建议可以更好地执行此操作,我们将不胜感激。

let bakeryA = ['saffron', 'eggs', 'tomato paste', 'coconut', 'custard'];
let bakeryB = ['milk', 'butter', 'cream cheese'];
let recipes = [
    {
        name: 'Coconut Sponge Cake',
        ingredients: ['coconut', 'cake base']
    },
    {
        name: 'Persian Cheesecake',
        ingredients: ['saffron', 'cream cheese']
    },
    {
        name: 'Custard Surprise',
        ingredients: ['custard', 'ground beef']
    }
];

const chooseRecipe = function(bakeryA, bakeryB, recipes) {
  let suitableRecipe = [];
  for (let i = 0; i < recipes.length; i++) {
    for (let j = 0; j < recipes[i].ingredients.length; j++) {
      for (let k = 0; k < bakeryA.length; k++) {
        if (bakeryA[k] === recipes[i].ingredients[j]) {
          for (let l = 0; l < bakeryB.length; l++) {
            for (let m = 0; m < recipes[i].ingredients; m++) {
              if (bakeryB[l] === recipes[i].ingredients[m]) {
                suitableRecipe.push(recipes[i].name);
              }
            }
          }
        }
      }
    }
  }
  return suitableRecipe;
}

console.log(chooseRecipe(bakeryA, bakeryB, recipes));

有一种更简洁的方法可以做到这一点,它涉及使用 Sets。假设 bakeryAbakeryB 列出每种成分一次:

let bakeryA = ['saffron', 'eggs', 'tomato paste', 'coconut', 'custard'];
let bakeryB = ['milk', 'butter', 'cream cheese'];
let recipes = [
    {
        name: 'Coconut Sponge Cake',
        ingredients: ['coconut', 'cake base']
    },
    {
        name: 'Persian Cheesecake',
        ingredients: ['saffron', 'cream cheese']
    },
    {
        name: 'Custard Surprise',
        ingredients: ['custard', 'ground beef']
    }
];

const chooseRecipe = function(bakeryA, bakeryB, recipes) {
  let aIngredients = new Set(bakeryA);
  let bIngredients = new Set(bakeryB);
  return recipes.filter(recipe => 
     recipe.ingredients.every(ingredient =>
         aIngredients.has(ingredient) || bIngredients.has(ingredient))
  );
}

console.log(chooseRecipe(bakeryA, bakeryB, recipes));

一些注意事项:

这种方法也更有效,因为它使您不必循环 5 (!) 次,循环会变得非常非常慢 bakeryAbakeryBingredients并且recipes变得越来越大。

我建议您使用方便的数组函数,例如 filter、find 和一些用于此类操作的函数。但是,如果您只是想知道为什么您的代码不起作用,有一个简单的解决方法。

您在最内层的 for 循环中缺少一个 .length。正确的循环是:

for (let m = 0; m < recipes[i].ingredients.length; m++) {
...
}

您可以通过使用可用的数组功能使其更加简洁。解决方案可能如下所示:

const choose = (bakeryA, bakeryB, recipes) => recipes.filter(
    ({ingredients}) => bakeryA.some(i => ingredients.includes(i)) && bakeryB.some(i => ingredients.includes(i))
);