如何在检查输入值的同时过滤数组?
2022-04-18
491
我在尝试过滤数组时遇到问题(见下文),我尝试过滤食谱,同时检查某种成分是否在食谱中。
下面是我的问题的简单示例。 首先是 JSON
{"recipes": [
{
"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"
}
]
}]
}
<input class="input" />
<script>
const input = document.querySelector(".input")
async function getRecipes() {
const response = await (await fetch("./recipes.json")).json();
const recipes = response.recipes;
return ({ recipes: [...recipes] });
};
function filter(recipes) {
input.addEventListener("input", () => {
var filteredRecipes = recipes.filter(recipe => {
return recipe.ingredients.ingredient.toLowerCase().includes(input.value.toLowerCase())
})
console.log(filteredRecipes)
})
}
async function init() {
const { recipes } = await getRecipes();
filter(recipes)
}
init()
</script>
此错误出现在控制台中:
index.html:23 Uncaught TypeError: Cannot read properties of undefined (reading 'toLowerCase')
这完全没问题,因为每种成分都不是一种成分。我尝试对成分数组进行 forEach,但无法获得结果。
因此,filteredRecipes 应该返回这里,或者我的食谱,或者一个空数组。
提前致谢
3个回答
-
由于
recipe.ingredients
是一个数组,因此您必须使用.filter()
或其等效函数来检查成分是否包含搜索到的文本。
将您的
filter
函数更改为类似以下内容
function filter(recipes) {
input.addEventListener("input", () => {
var filteredRecipes = recipes.filter(recipe => {
return recipe.ingredients.filter(({ingredient}) => ingredient.toLowerCase().includes(input.value.toLowerCase())).length > 0
})
console.log(filteredRecipes)
})
}
ruleboy21
2022-04-18
这可能是由于 init 函数中 fetch 前面的“await”引起的。请尝试这样做;
async function init() {
const { recipes } = getRecipes().then(res => filter(res.recipes))
.catch(err => //catch any error
);
}
Orçun Güler
2022-04-18
每次过滤时,您都会在输入上绑定一个事件监听器。
您只需要在启动时设置一次。
还提供更详细的替代方案:
function filter_recipes(recipes, value) {
let ans = []
let filter = value.toLowerCase()
for (let recipe of recipes) {
for (let item of recipe.ingredients) {
if (item.ingredient.toLowerCase().includes(filter)) {
ans.push(recipe)
}
}
}
return ans
}
madprops
2022-04-18