JS数组过滤食谱问题:Array.every()筛选失效求助
问题分析与修复:根据冰箱食材过滤食谱
你的代码存在这几个核心问题:
- 逻辑完全颠倒:你当前的逻辑是拿冰箱里的每一样食材,去检查「食谱的所有食材是否都包含这个冰箱食材」——这和你要实现的「食谱所有食材都在冰箱里」完全相反。比如carbonara里有eggs,当循环到冰箱里的oil时,
eggs.includes("oil")返回false,every直接判定不通过,根本不会触发push。 - 嵌套forEach导致重复添加:就算逻辑正确,用
fridge.forEach遍历的话,每匹配一个冰箱食材就会push一次食谱,会把符合条件的食谱多次加入结果数组。 - forEach里的return无效:
forEach无法通过return终止循环,你写的return filteredPlates只会终止当前的回调函数,不会跳出外层循环,也不会提前结束整个过滤逻辑。
修复后的代码
正确的逻辑是:遍历所有食谱,筛选出「该食谱的每一种食材都存在于冰箱数组中」的项。用Array.filter()配合Array.every()就能简洁实现:
const plates = [ { name: "carbonara", ingredients: ["eggs", "milk", "pepper", "pasta", "cheese"], time: 30, difficulty: "easy", }, { name: "oil_pepper", ingredients: ["oil", "pepper", "pasta", "garlic"], time: 20, difficulty: "medium", }, { name: "tomato", ingredients: ["pasta", "tomato", "garlic", "onion"], time: "30", difficulty: "hard", }, ]; const fridge = ["oil", "pepper", "pasta", "garlic"]; // 直接用filter生成结果数组,无需手动维护空数组 const filteredPlates = plates.filter(plate => { // 检查当前食谱的所有食材是否都存在于冰箱中 return plate.ingredients.every(ingredient => fridge.includes(ingredient)); }); console.log(filteredPlates); // 输出:[{name: "oil_pepper", ingredients: ["oil", "pepper", "pasta", "garlic"], time: 20, difficulty: "medium"}]
额外说明
- 用
filter()直接生成结果数组,比手动push更符合函数式编程风格,也避免了重复添加的问题。 every()在这里的作用是确保食谱的每一项食材都满足「存在于冰箱」的条件,只要有一个食材不在冰箱里,every就会返回false,该食谱会被过滤掉。- 注意第三个食谱的
time是字符串类型"30",和其他两个的数字类型不一致,如果后续有时间相关的计算,建议统一类型。
内容的提问来源于stack exchange,提问作者naicio
相关产品推荐
相关产品推荐

