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'
},
]
CodePudding user response:
This should do it
Use:
Object.entries(cocktail[0])
to get an array of [key, value] from the datafilter
to get the Ingredients and Measures - and ignore the ones withnull
valuesreduce
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);
CodePudding user response:
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
CodePudding user response:
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)
CodePudding user response:
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/[email protected]/lodash.min.js"></script>