eGa*_*ood 1 javascript jquery javascript-objects
目前正在开发一个用于搜索饮料配方的网络应用程序。这个想法是搜索一种饮料并向用户显示名称、成分和尺寸。我正在努力寻找一种有效的方法来迭代 API 响应,因为它们不会以数组形式返回。下面是一个响应示例。
dateModified :"2015-08-18 14:54:32"
idDrink:"11668"
strAlcoholic:"Alcoholic
strCategory:"Ordinary Drink"
strDrink: "Long Island Tea"
strDrinkThumb: "https://www.thecocktaildb.com/images/media/drink/ywxwqs1439906072.jpg"
strGlass: "Highball glass"
strIBA:null
strIngredient1: "Vodka"
strIngredient2:"Light rum"
strIngredient3:"Gin"
strIngredient4:"Tequila"
strIngredient5: "Lemon"
strIngredient6: "Coca-Cola"
strIngredient7:""
strIngredient8:""
strIngredient9:""
strIngredient10:""
strIngredient11:""
strIngredient12:""
strIngredient13:""
strIngredient14:""
strIngredient15:""
strInstructions:
"Combine all ingredients (except cola) and pour over ice in a highball glass. Add the splash of cola for color. Decorate with a slice of lemon and serve."
strMeasure1:"1/2 oz "
strMeasure2:"1/2 oz "
strMeasure3: "1/2 oz "
strMeasure4: "1/2 oz "
strMeasure5:"Juice of 1/2 "
strMeasure6:"1 splash "
strMeasure7:" "
strMeasure8:" "
strMeasure9:" "
strMeasure10:" "
strMeasure11:" "
strMeasure12:" "
strMeasure13:" "
strMeasure14:" "
strMeasure15:" "
strVideo: null
Run Code Online (Sandbox Code Playgroud)
目标是将一些信息映射到表中。是否有一种迭代方法来清理这个问题,以便只返回具有值的成分?或者创建一个单独的文件来格式化成分是最好的解决方案吗?
目前,我能想到的阻力最小的路径是创建以下 15 次:strIngredient1 !=""。
下面是API调用:
$('#drinkSearch').click(function(){
var word = document.getElementById("sbar").value;
event.preventDefault();
console.log(word)
$.getJSON("https://www.thecocktaildb.com/api/json/v1/1/search.php?s="+ word, function(Result) {
console.log(Result)
Result.drinks.forEach(function(ingredients){
var ing1 = ingredients.strIngredient1;
console.log(ing1);
})
});
});
Run Code Online (Sandbox Code Playgroud)
API 会为每种饮料返回一个对象,其中包含诸如strIngredient1through之类的键strIngredient15、strMeasure1throughstrMeasure15等键。\xe2\x80\x8a\xe2\x80\x94\xe2\x80\x8a 的设计确实很糟糕。
您可以将所有这些收集到一个数组中。有两种不同的处理空值的方法。您可以简单地过滤空值或将度量与其成分相匹配:
\n\n这些方法只是从每个要构建的数组中删除空值。这可能会导致不一致,因为键实际上在位置上strMeasure依赖于strIngredient键。寻找匹配的方法来解决这个问题。
另一个问题是成分和措施有时可能会出现问题。配套的\xe2\x80\x99没有这个问题。
\n\nResult.drinks.forEach((drink) => {\n const drinkEntries = Object.entries(drink),\n ingredientsArray = drinkEntries\n .filter(([key, value]) => key.startsWith("strIngredient") && value && value.trim())\n .map(([key, value]) => value),\n measuresArray = drinkEntries\n .filter(([key, value]) => key.startsWith("strMeasure") && value && value.trim())\n .map(([key, value]) => value);\n\n console.log("Ingredients:", ingredientsArray);\n console.log("Measures:", measuresArray);\n});\nRun Code Online (Sandbox Code Playgroud)\n\n在 中filter,key.startsWith("strIngredient")确保您获得正确的十五个键,并&& value && value.trim()确保该值既不是null,也不是空,也不是空格(因此trim)。所有三种变体都是随机使用的。
冗余较少的形式可能如下所示:
\n\nResult.drinks.forEach((drink) => {\n const drinkEntries = Object.entries(drink),\n [\n ingredientsArray,\n measuresArray\n ] = [\n "strIngredient",\n "strMeasure"\n ].map((keyName) => drinkEntries\n .filter(([key, value]) => key.startsWith(keyName) && value && value.trim())\n .map(([key, value]) => value));\n\n console.log("Ingredients:", ingredientsArray);\n console.log("Measures:", measuresArray);\n});\nRun Code Online (Sandbox Code Playgroud)\n\n这种方法首先为strIngredients 和strMeasures 构建两个数组。数字键用 提取parseInt(key.slice(keyName.length))。Object.assign将多个{key: value}对象放入一个数组中(其中keys 是数字)意味着使用这些数字键和这些值构建一个数组。1
然后对值进行过滤,以便如果有任何具有相同索引的值,则保留它们值非空时保留这些值。
\n\nResult.drinks.forEach((drink) => {\n const drinkEntries = Object.entries(drink),\n // This part build arrays out of the two sets of keys\n [\n ingredientsArray,\n measuresArray\n ] = [\n "strIngredient",\n "strMeasure"\n ].map((keyName) => Object.assign([], ...drinkEntries\n .filter(([key, value]) => key.startsWith(keyName))\n .map(([key, value]) => ({[parseInt(key.slice(keyName.length))]: value})))),\n\n // This part filters empty values based on the ingredients\n {\n finalIngredients,\n finalMeasures\n } = ingredientsArray.reduce((results, value, index) => {\n if(value && value.trim() || measuresArray[index] && measuresArray[index].trim()){\n results.finalIngredients.push(value);\n results.finalMeasures.push(measuresArray[index]);\n }\n\n return results;\n }, {\n finalIngredients: [],\n finalMeasures: []\n }),\n\n // Optional: zip both arrays\n ingredientsWithMeasures = finalIngredients\n .map((value, index) => [finalMeasures[index], value]);\n\n // Output\n console.log("Ingredients:", finalIngredients);\n console.log("Measures:", finalMeasures);\n\n console.log("All ingredients and measures:\\n", ingredientsWithMeasures\n .map(([measure, ingredient]) => `${(measure || "").trim()} ${(ingredient || "").trim()}`)\n .join("\\n"));\n});\nRun Code Online (Sandbox Code Playgroud)\n\n1:从对象构建数组通常也适用于Array.from,但它length也需要一个属性。我没有计算,而是继续使用Object.assign。