【问题标题】:JS For Loops Returning Empty ArrayJS For 循环返回空数组
【发布时间】:2021-05-24 05:40:05
【问题描述】:

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));

【问题讨论】:

  • for (let m = 0; m &lt; recipes[i].ingredients; m++) { 缺少 .length for ingredients 吗?
  • 就是这样!太感谢了!不敢相信我错过了!

标签: javascript arrays for-loop object nested-loops


【解决方案1】:

有一种更简洁的方法可以做到这一点,它涉及使用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 (!) 次,随着 bakeryAbakeryBingredientsrecipes 变得越来越大,这将变得非常缓慢.

【讨论】:

    【解决方案2】:

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

    您在最里面的 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))
    );
    

    【讨论】:

    • 谢谢!我错过了 .length 的事实确实说明了为什么这样的循环不是一个好主意。我将考虑为此使用过滤器功能。
    猜你喜欢
    • 2022-11-16
    • 2021-05-21
    • 1970-01-01
    • 2022-12-12
    • 2021-04-24
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多