JS For 循环返回空数组
JS For Loops Returning Empty Array
chooseRecipe
函数应该将 bakeryA
和 bakeryB
中的数组与每个 recipe
的 ingredients
进行比较。如果 bakeryA
和 bakeryB
每个都有一个配方的成分,那么应该打印配方的名称。在这种情况下,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。假设 bakeryA
和 bakeryB
列出每种成分一次:
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));
一些注意事项:
Array.prototype.every
允许您检查食谱中的每种成分是否在 bakeryA
或 bakeryB
中。
Array.prototype.filter
用于迭代并过滤掉不符合指定条件的值。
这种方法也更有效,因为它使您不必循环 5 (!) 次,循环会变得非常非常慢 bakeryA
、bakeryB
、ingredients
并且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))
);
chooseRecipe
函数应该将 bakeryA
和 bakeryB
中的数组与每个 recipe
的 ingredients
进行比较。如果 bakeryA
和 bakeryB
每个都有一个配方的成分,那么应该打印配方的名称。在这种情况下,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。假设 bakeryA
和 bakeryB
列出每种成分一次:
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));
一些注意事项:
Array.prototype.every
允许您检查食谱中的每种成分是否在bakeryA
或bakeryB
中。Array.prototype.filter
用于迭代并过滤掉不符合指定条件的值。
这种方法也更有效,因为它使您不必循环 5 (!) 次,循环会变得非常非常慢 bakeryA
、bakeryB
、ingredients
并且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))
);