This this data:
const cocktail = [
{
"idDrink":"13070",
"strDrink":"Fahrenheit 5000",
"strGlass":"Shot glass",
"strInstructions":"Cover bottom of shot gla",
"strIngredient1":"Firewater",
"strIngredient2":"Absolut Peppar",
"strIngredient3":"Tabasco sauce",
"strIngredient4":null,
"strMeasure1":"1/2 oz ",
"strMeasure2":"1/2 oz ",
"strMeasure3":"1 dash ",
"strMeasure4":null
}
]
it's my hope to return an array of objects that populate the non- null
values of each strMeasure[n] and strIngredient[n] :
[
{
strMeasure1: value,
strIngredient1: value
},
{
strMeasure2: value,
strIngredient2: value
},
…
]
from cocktail
array above, the ideal output would be:
[
{
measure: '1/2 oz',
name: 'Firewater'
},
{
measure: '1/2 oz',
name: 'Absolut Peppar'
},
{
measure: '1 dash',
name: 'Tobasco sauce'
},
]
This should do it
Use:
Object.entries(cocktail[0])
to get an array of [key, value] from the data filter
to get the Ingredients and Measures - and ignore the ones with null
values reduce
to build up the resulting array Like this:
const cocktail = [ { "idDrink":"13070", "strDrink":"Fahrenheit 5000", "strGlass":"Shot glass", "strInstructions":"Cover bottom of shot gla", "strIngredient1":"Firewater", "strIngredient2":"Absolut Peppar", "strIngredient3":"Tabasco sauce", "strIngredient4":null, "strMeasure1":"1/2 oz ", "strMeasure2":"1/2 oz ", "strMeasure3":"1 dash ", "strMeasure4":null } ] const result = Object.entries(cocktail[0]).filter(([k,v])=>v && k.match(/^str(Ingredient|Measure)\d+$/)).reduce((acc, [k, v]) => { const [t, n] = k.match(/^str(Ingredient|Measure)(\d+)$/).slice(1); acc[n-1] = {...acc[n-1], [t]:v}; return acc; }, []) console.log(result);
You could also do it without the filter step
const result = Object.entries(cocktail[0])
.reduce((acc, [k, v]) => {
if (v) {
const [t, n] = k.match(/^str(Ingredient|Measure)(\d+)$/)?.slice(1) ?? [] ;
acc[n-1] = {...acc[n-1], [t]:v};
}
return acc;
}, [])
console.log(result);
It looks like you could benefit from using javascripts map() method for parsing out the specific key value pairs from within the object in the array. There are also several ways you could extract the values you want from inside the object such as through dot notation. I have attached a few links here that are very helpful and will give you a much deeper and basic understanding of how to achieve this.
From an array of objects, extract value of a property as array
https://bobbyhadz.com/blog/javascript-convert-array-of-objects-to-array-of-values
You can first create an array of object which will have measure
and id
. Then use the id
to get the value from cocktail array
const cocktail = [{ "idDrink": "13070", "strDrink": "Fahrenheit 5000", "strGlass": "Shot glass", "strInstructions": "Cover bottom of shot gla", "strIngredient1": "Firewater", "strIngredient2": "Absolut Peppar", "strIngredient3": "Tabasco sauce", "strIngredient4": null, "strMeasure1": "1/2 oz ", "strMeasure2": "1/2 oz ", "strMeasure3": "1 dash ", "strMeasure4": null }] const obj = []; for (let keys in cocktail[0]) { if (keys.includes('strIngredient')) { const tempObj = { measure: cocktail[0][keys], id: keys.charAt(keys.length - 1) } obj.push(tempObj) } } obj.forEach((elem) => elem.value = cocktail[0][`strMeasure${elem.id}`]) console.log(obj)
Lodash if you don't mind
const cocktail = {"idDrink":"13070","strDrink":"Fahrenheit 5000","strGlass":"Shot glass","strInstructions":"Cover bottom of shot gla","strIngredient1":"Firewater","strIngredient2":"Absolut Peppar","strIngredient3":"Tabasco sauce","strIngredient4":null,"strMeasure1":"1/2 oz ","strMeasure2":"1/2 oz ","strMeasure3":"1 dash ","strMeasure4":null}; const parseKey = (str) => [...str.matchAll(/(strIngredient|strMeasure)(\d+)/g)].flat(); const maping = { strIngredient: 'name', strMeasure: 'measure' }; const iter = (acc, value, key) => { const [, keyName, keyNumber] = parseKey(key); if (value && keyName) { acc[keyNumber]??= {}; acc[keyNumber][maping[keyName]] = value; } return acc; }; const result = _(cocktail).transform(iter, {}).values(); console.log(result);
.as-console-wrapper { max-height: 100%;important: top: 0 }
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.