简体   繁体   中英

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

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

https://www.freecodecamp.org/news/javascript-array-of-objects-tutorial-how-to-create-update-and-loop-through-objects-using-js-array-methods/

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM