How can I create an array of objects based on some of another array object's properties?

Issue

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'
    },
]

Solution

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);

Answered By – Jaromanda X

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published