饮品配方Web应用:遍历键含文本数字的非数组API响应求助
Hey there! I get it, dealing with API responses that don’t come in a neat array can be a bit frustrating—especially when you need to pull out scattered data like ingredients and their measures. Let’s break down how to efficiently parse that response into something usable for your drink recipe app.
Step 1: Understand the API Response Structure
From your example, it looks like the API returns a single object with keys like strDrink, strAlcoholic, and sequential keys for ingredients/measures (e.g., strIngredient1, strMeasure1, strIngredient2, strMeasure2, etc.). The goal is to group these paired keys into a clean list of ingredients.
Step 2: Efficiently Extract Ingredients & Measures
Instead of manually checking each possible ingredient key (which is error-prone and inflexible), we can use JavaScript’s object methods to dynamically parse the data. Here are two solid approaches:
Approach 1: Fixed-Loop (Good if you know the max number of ingredients)
Most drink APIs cap ingredients at around 15, so a simple loop works here—it’s straightforward and fast:
// Assume this is your parsed API response object const drinkData = { dateModified: "2015-08-18 14:54:32", idDrink: "11668", strAlcoholic: "Alcoholic", strCategory: "Ordinary Drink", strDrink: "Long Island Tea", strIngredient1: "Vodka", strMeasure1: "1/2 oz", strIngredient2: "Gin", strMeasure2: "1/2 oz", strIngredient3: "White Rum", strMeasure3: "1/2 oz", // ... more ingredients/measures }; // Extract ingredients const ingredients = []; const maxIngredients = 15; // Adjust based on API docs for (let i = 1; i <= maxIngredients; i++) { const ingredient = drinkData[`strIngredient${i}`]; const measure = drinkData[`strMeasure${i}`]; // Only add if the ingredient exists (skip empty entries) if (ingredient?.trim()) { ingredients.push({ name: ingredient.trim(), measure: measure?.trim() || "To taste" }); } } // Now you have a clean array of ingredients! console.log(ingredients);
Approach 2: Dynamic Filtering (Flexible, no hardcoded max)
If you want to avoid hardcoding the maximum number of ingredients, use Object.entries() to filter and map the keys dynamically:
const ingredients = Object.entries(drinkData) // Filter only ingredient keys .filter(([key]) => key.startsWith("strIngredient")) // Map each ingredient to its corresponding measure .map(([key, ingredientName]) => { // Get the index from the ingredient key (e.g., "1" from "strIngredient1") const index = key.replace("strIngredient", ""); const measure = drinkData[`strMeasure${index}`]; return { name: ingredientName.trim(), measure: measure?.trim() || "To taste" }; }) // Remove any entries where the ingredient name is empty .filter(item => item.name);
Step 3: Display the Data to Users
Once you have the clean ingredients array and core drink details, you can easily render them in your UI. For example, in React:
function DrinkDetails({ drinkData, ingredients }) { return ( <div className="drink-card"> <h2>{drinkData.strDrink}</h2> <p><strong>Category:</strong> {drinkData.strCategory}</p> <p><strong>Alcoholic:</strong> {drinkData.strAlcoholic}</p> <h3>Ingredients:</h3> <ul> {ingredients.map((ing, idx) => ( <li key={idx}>{ing.measure} {ing.name}</li> ))} </ul> </div> ); }
Why This Works
Both approaches are efficient because they run in O(n) time complexity (where n is the number of keys in the response object). The fixed loop is slightly faster since it avoids filtering all keys, but the dynamic approach is more robust if the API ever changes the number of ingredients allowed.
Just make sure to handle edge cases like missing measures (hence the "To taste" fallback) and empty ingredient entries (since some drinks might have fewer ingredients than the max).
内容的提问来源于stack exchange,提问作者eGathergood

