Michael
Michael

Reputation: 987

Object into Array conversion

I have this state Object in a class:

state = {
    ingredients: {
        salad: 1,
        bacon: 5, 
        cheese: 2, 
        meat: 2
    }
}

and want to convert it into an array that gets also the value number, like this:

const burger = (props) => {
const transformedIngredients = Object.keys(props.ingredients)
    .map(igKey => {
        return [...Array(props.ingredients[igKey])].map((_,i)=>{
           return <BurgerIngredient key={igKey + i} type={igKey}/>
        });
    });

    console.log(transformedIngredients)
    return(
        <div className={classes.Burger}> 
        <BurgerIngredient type="bread-top" />
        <BurgerIngredient type="cheese" />
        <BurgerIngredient type="meat" />
        <BurgerIngredient type="bread-bottom" />
    </div>
  );
};
export default burger;

I succeeded in doing it following a tutorial and to be honest I do not completely understand what is happening here. especially this part:

return [...Array(props.ingredients[igKey])].map((_,i)=>{
       return <BurgerIngredient key={igKey + i} type={igKey}/>
    });

any help would be greatly appreciated! Thank you!

Upvotes: 2

Views: 849

Answers (2)

uniqueok
uniqueok

Reputation: 21

props.ingredients[igKey]

returns a number, 5 for example for bacon.

[...Array(props.ingredients[igKey])]

returns an array of n elements. Those elements are undefined as you haven't filled them yet.

A solution would be:

[...Array(props.ingredients[igKey])].fill(igKey)

Or simply:

Array(state.ingredients[igKey]).fill(igKey)

That results in:

["salad", "bacon", "bacon", "bacon", "bacon", "bacon", "cheese", "cheese", "meat", "meat"]

Upvotes: 0

Jonas Wilms
Jonas Wilms

Reputation: 138235

igKey is one of the keys of your ingredients, bacon for example. Now that is looked up in the ingredients with

 props.ingredients[igKey]

which then results in the amount, 5 in this case. Now that is used to build up an array with that length:

 Array(5) // { length: 5 }

Now that array is a sparse array, it has nothing in it. To be able to iterate over it with map, it has to be filled with not defined values, therefore that sparse array is spread into a new array, which turns it into a filled array:

 [...Array(5)] // { length: 5, 0: undefined, 1: undefined, 2: ... }

Now that empty array with 5 entries will be mapped to an array with 5 Burger ingredients.


By the way more elegant IMO:

 Array.from(
   { length: props.infredients[igKey] },
   (_, i) => <BurgerIngredient key={igKey + i} type={igKey}/>
 )

Upvotes: 6

Related Questions