如何用用户输入的成分数组过滤含Ingredients对象数组的饮品JSON
饮品JSON数据筛选需求
背景说明
我有一个包含300多种饮品对象的JSON文件,每个对象包含饮品类别、名称、是否含酒精、制作说明等字段,其中Ingredients字段是包含Ingredient(成分名称)和Measurement(用量)的对象数组。
示例饮品对象
{ "strCategory": "Beer", "strDrink": "110 in the shade", "strAlcoholic": "Alcoholic", "dateModified": "2016-02-03 14:51:57", "strInstructionsIT": "Riempi un bicchierino di tequila.\r\nRiempi un boccale di birra con la birra chiara.\r\nMetti il bicchierino nella birra e bevi velocemente.", "idDrink": "15423", "strDrinkThumb": "https://www.thecocktaildb.com/images/media/drink/xxyywq1454511117.jpg", "strCreativeCommonsConfirmed": "No", "strGlass": "Beer Glass", "Ingredients": [ { "Ingredient": "Lager", "Measurement": "16 oz " }, { "Measurement": "1.5 oz ", "Ingredient": "Tequila" } ], "strInstructionsDE": "Shooter tröpfchenweise in ein Glas geben. Mit Bier füllen.", "strInstructions": "Drop shooter in glass. Fill with beer" }, { "Ingredients": [ { "Ingredient": "Malibu Rum", "Measurement": "1/2 oz " }, { "Ingredient": "Light Rum", "Measurement": "1/2 oz " }, { "Ingredient": "Rum", "Measurement": "1/2 oz" }, { "Measurement": "1 oz ", "Ingredient": "Dark Creme De Cacao" }, { "Measurement": "1 oz ", "Ingredient": "Cointreau" }, { "Ingredient": "Milk", "Measurement": "3 oz " }, { "Ingredient": "Coconut Liqueur", "Measurement": "1 oz " }, { "Measurement": "1 cup ", "Ingredient": "Vanilla Ice-cream" } ], "strInstructionsDE": "Alle Zutaten vermengen. Mischen, bis alles glatt ist. Auf Wunsch mit Schokoladenraspeln garnieren.", "strDrinkThumb": "https://www.thecocktaildb.com/images/media/drink/rvwrvv1468877323.jpg", "strCategory": "Shake", "strInstructions": "Combine all ingredients. Blend until smooth. Garnish with chocolate shavings if desired.", "idDrink": "14588", "strCreativeCommonsConfirmed": "No", "strInstructionsIT": "Combina tutti gli ingredienti.\r\nFrulla fino a che è liscio.\r\nGuarnire con scaglie di cioccolato se lo si desidera.", "dateModified": "2016-07-18 22:28:43", "strGlass": "Beer Mug", "strDrink": "151 Florida Bushwacker", "strAlcoholic": "Alcoholic" }
用户输入示例
let Ingredients_Entered_By_User = ["Vodka", "Rum", "Lemonade"];
核心需求
筛选出同时包含用户输入数组中所有成分的饮品对象,而非仅包含任一成分的对象。
实现方案
代码实现
// 假设你的饮品数据数组为drinksData const drinksData = [/* 你的300+饮品JSON数据 */]; // 用户输入的成分数组 const Ingredients_Entered_By_User = ["Vodka", "Rum", "Lemonade"]; // 标准化成分名称(统一转小写+去空格,避免大小写/空格导致的匹配失败) const normalizedUserIngredients = Ingredients_Entered_By_User.map(ing => ing.trim().toLowerCase()); // 筛选符合条件的饮品 const filteredDrinks = drinksData.filter(drink => { // 跳过Ingredients字段异常的饮品 if (!drink.Ingredients || !Array.isArray(drink.Ingredients) || drink.Ingredients.length === 0) { return false; } // 提取当前饮品的所有成分并标准化 const drinkIngredientNames = drink.Ingredients .map(item => item.Ingredient?.trim().toLowerCase()) .filter(Boolean); // 过滤空值或无效成分 // 检查用户输入的每一种成分是否都存在于当前饮品中 return normalizedUserIngredients.every(ing => drinkIngredientNames.includes(ing)); }); // 输出筛选结果 console.log(filteredDrinks);
额外说明
- 大小写/空格兼容:通过统一转小写和去除首尾空格,避免因成分名称格式不一致(比如"Rum"和" rum ")导致的匹配失败
- 异常处理:增加了对
Ingredients字段异常情况的判断,避免空值或非数组结构引发代码报错 - 模糊匹配扩展:如果需要支持模糊匹配(比如用户输入"Rum"时匹配"Light Rum"),可以将判断逻辑修改为:
return normalizedUserIngredients.every(ing => drinkIngredientNames.some(drinkIng => drinkIng.includes(ing)) );
内容的提问来源于stack exchange,提问作者ssethzz
相关产品推荐
相关产品推荐

