Transform a javascript object to an array based on value of each key in the original object











up vote
0
down vote

favorite












I have an object of ingredients to be added to a burger. Its structure is as follows:



Input



    ingredients: {
salad: 1,
cheese: 2,
meat: 2,
}


I want to transform it to an array of JSX elements. Each key in the original object has to be mapped to the number of JSX elements equivalent to the value of the ingredient in the ingredients objects. So the result array should look like so:



Output



[
<BurgerIngredient type="salad" />,
<BurgerIngredient type="cheese" />,
<BurgerIngredient type="cheese" />,
<BurgerIngredient type="meat" />,
<BurgerIngredient type="meat" />,
]


My solution is as follows:



function getBurgerIngredients() {
const ingredientNames = Object.keys(props.ingredients);
const transformedIngredients = ingredientNames.map( (ingredientName) => {
let burgerIngredientElements = ;
for(let i=0; i<props.ingredients[ingredientName]; i++) {
burgerIngredientElements.push(
<BurgerIngredient type={ingredientName} />
)
}
return [...burgerIngredientElements]
});

return transformedIngredients;
}


I'm aware that it's not the most elegant solution. Can anyone suggest any improvement(s)?










share|improve this question




























    up vote
    0
    down vote

    favorite












    I have an object of ingredients to be added to a burger. Its structure is as follows:



    Input



        ingredients: {
    salad: 1,
    cheese: 2,
    meat: 2,
    }


    I want to transform it to an array of JSX elements. Each key in the original object has to be mapped to the number of JSX elements equivalent to the value of the ingredient in the ingredients objects. So the result array should look like so:



    Output



    [
    <BurgerIngredient type="salad" />,
    <BurgerIngredient type="cheese" />,
    <BurgerIngredient type="cheese" />,
    <BurgerIngredient type="meat" />,
    <BurgerIngredient type="meat" />,
    ]


    My solution is as follows:



    function getBurgerIngredients() {
    const ingredientNames = Object.keys(props.ingredients);
    const transformedIngredients = ingredientNames.map( (ingredientName) => {
    let burgerIngredientElements = ;
    for(let i=0; i<props.ingredients[ingredientName]; i++) {
    burgerIngredientElements.push(
    <BurgerIngredient type={ingredientName} />
    )
    }
    return [...burgerIngredientElements]
    });

    return transformedIngredients;
    }


    I'm aware that it's not the most elegant solution. Can anyone suggest any improvement(s)?










    share|improve this question


























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I have an object of ingredients to be added to a burger. Its structure is as follows:



      Input



          ingredients: {
      salad: 1,
      cheese: 2,
      meat: 2,
      }


      I want to transform it to an array of JSX elements. Each key in the original object has to be mapped to the number of JSX elements equivalent to the value of the ingredient in the ingredients objects. So the result array should look like so:



      Output



      [
      <BurgerIngredient type="salad" />,
      <BurgerIngredient type="cheese" />,
      <BurgerIngredient type="cheese" />,
      <BurgerIngredient type="meat" />,
      <BurgerIngredient type="meat" />,
      ]


      My solution is as follows:



      function getBurgerIngredients() {
      const ingredientNames = Object.keys(props.ingredients);
      const transformedIngredients = ingredientNames.map( (ingredientName) => {
      let burgerIngredientElements = ;
      for(let i=0; i<props.ingredients[ingredientName]; i++) {
      burgerIngredientElements.push(
      <BurgerIngredient type={ingredientName} />
      )
      }
      return [...burgerIngredientElements]
      });

      return transformedIngredients;
      }


      I'm aware that it's not the most elegant solution. Can anyone suggest any improvement(s)?










      share|improve this question















      I have an object of ingredients to be added to a burger. Its structure is as follows:



      Input



          ingredients: {
      salad: 1,
      cheese: 2,
      meat: 2,
      }


      I want to transform it to an array of JSX elements. Each key in the original object has to be mapped to the number of JSX elements equivalent to the value of the ingredient in the ingredients objects. So the result array should look like so:



      Output



      [
      <BurgerIngredient type="salad" />,
      <BurgerIngredient type="cheese" />,
      <BurgerIngredient type="cheese" />,
      <BurgerIngredient type="meat" />,
      <BurgerIngredient type="meat" />,
      ]


      My solution is as follows:



      function getBurgerIngredients() {
      const ingredientNames = Object.keys(props.ingredients);
      const transformedIngredients = ingredientNames.map( (ingredientName) => {
      let burgerIngredientElements = ;
      for(let i=0; i<props.ingredients[ingredientName]; i++) {
      burgerIngredientElements.push(
      <BurgerIngredient type={ingredientName} />
      )
      }
      return [...burgerIngredientElements]
      });

      return transformedIngredients;
      }


      I'm aware that it's not the most elegant solution. Can anyone suggest any improvement(s)?







      jsx






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 19 at 20:48









      200_success

      127k15148411




      127k15148411










      asked Nov 19 at 12:53









      dinika saxena

      31




      31






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          0
          down vote



          accepted










          const ingredientNames = Object.keys(props.ingredients);


          Just be aware that anything that iterates/enumerates an object's keys (Object.keys, for-in, etc.) does not guarantee order. So it might not always be "salad, cheese, cheese, meat, meat" in the end. It just happens that most browsers iterate in the order they were created/added to the object, which is why it appears like so. If you want order, use an array to begin with.



              let burgerIngredientElements = ;
          for(let i=0; i<props.ingredients[ingredientName]; i++) {
          burgerIngredientElements.push(
          <BurgerIngredient type={ingredientName} />
          )
          }
          return [...burgerIngredientElements]


          Also, I don't think this code is doing what you think it's doing. You're pushing to an existing array, then spreading it's contents into another array. You're essentially just shallow-cloning. It might look rendered correctly (probably because JSX now does fragments) but the structure is questionable.





          Anyways, a more functional way to iterate from 0 to N is to create an array of N items (it doesn't matter what the values are) and operate on that array using array methods. One way this can be achieved is using Array and array.fill.



          Also, instead of a loop and an outer variable holding an array, you can use array.reduce with the accumulator being that array. That way, you don't have that extra mutable variable.



          Your code could look like this:



          function getBurgerIngredients() {
          const ingredients = props.ingredients

          return Object.keys(ingredients).reduce((c, ingredientName) => {
          const range = Array(ingredients[ingredientName]).fill()

          return [...c, ...range.map(() => (<BurgerIngredient type={ingredientName} />))]
          }, );
          }





          share|improve this answer





















          • Thanks, this helped a great deal (especially the part where you explain shallow-cloning) :)
            – dinika saxena
            Nov 19 at 18:11











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














           

          draft saved


          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f207976%2ftransform-a-javascript-object-to-an-array-based-on-value-of-each-key-in-the-orig%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          0
          down vote



          accepted










          const ingredientNames = Object.keys(props.ingredients);


          Just be aware that anything that iterates/enumerates an object's keys (Object.keys, for-in, etc.) does not guarantee order. So it might not always be "salad, cheese, cheese, meat, meat" in the end. It just happens that most browsers iterate in the order they were created/added to the object, which is why it appears like so. If you want order, use an array to begin with.



              let burgerIngredientElements = ;
          for(let i=0; i<props.ingredients[ingredientName]; i++) {
          burgerIngredientElements.push(
          <BurgerIngredient type={ingredientName} />
          )
          }
          return [...burgerIngredientElements]


          Also, I don't think this code is doing what you think it's doing. You're pushing to an existing array, then spreading it's contents into another array. You're essentially just shallow-cloning. It might look rendered correctly (probably because JSX now does fragments) but the structure is questionable.





          Anyways, a more functional way to iterate from 0 to N is to create an array of N items (it doesn't matter what the values are) and operate on that array using array methods. One way this can be achieved is using Array and array.fill.



          Also, instead of a loop and an outer variable holding an array, you can use array.reduce with the accumulator being that array. That way, you don't have that extra mutable variable.



          Your code could look like this:



          function getBurgerIngredients() {
          const ingredients = props.ingredients

          return Object.keys(ingredients).reduce((c, ingredientName) => {
          const range = Array(ingredients[ingredientName]).fill()

          return [...c, ...range.map(() => (<BurgerIngredient type={ingredientName} />))]
          }, );
          }





          share|improve this answer





















          • Thanks, this helped a great deal (especially the part where you explain shallow-cloning) :)
            – dinika saxena
            Nov 19 at 18:11















          up vote
          0
          down vote



          accepted










          const ingredientNames = Object.keys(props.ingredients);


          Just be aware that anything that iterates/enumerates an object's keys (Object.keys, for-in, etc.) does not guarantee order. So it might not always be "salad, cheese, cheese, meat, meat" in the end. It just happens that most browsers iterate in the order they were created/added to the object, which is why it appears like so. If you want order, use an array to begin with.



              let burgerIngredientElements = ;
          for(let i=0; i<props.ingredients[ingredientName]; i++) {
          burgerIngredientElements.push(
          <BurgerIngredient type={ingredientName} />
          )
          }
          return [...burgerIngredientElements]


          Also, I don't think this code is doing what you think it's doing. You're pushing to an existing array, then spreading it's contents into another array. You're essentially just shallow-cloning. It might look rendered correctly (probably because JSX now does fragments) but the structure is questionable.





          Anyways, a more functional way to iterate from 0 to N is to create an array of N items (it doesn't matter what the values are) and operate on that array using array methods. One way this can be achieved is using Array and array.fill.



          Also, instead of a loop and an outer variable holding an array, you can use array.reduce with the accumulator being that array. That way, you don't have that extra mutable variable.



          Your code could look like this:



          function getBurgerIngredients() {
          const ingredients = props.ingredients

          return Object.keys(ingredients).reduce((c, ingredientName) => {
          const range = Array(ingredients[ingredientName]).fill()

          return [...c, ...range.map(() => (<BurgerIngredient type={ingredientName} />))]
          }, );
          }





          share|improve this answer





















          • Thanks, this helped a great deal (especially the part where you explain shallow-cloning) :)
            – dinika saxena
            Nov 19 at 18:11













          up vote
          0
          down vote



          accepted







          up vote
          0
          down vote



          accepted






          const ingredientNames = Object.keys(props.ingredients);


          Just be aware that anything that iterates/enumerates an object's keys (Object.keys, for-in, etc.) does not guarantee order. So it might not always be "salad, cheese, cheese, meat, meat" in the end. It just happens that most browsers iterate in the order they were created/added to the object, which is why it appears like so. If you want order, use an array to begin with.



              let burgerIngredientElements = ;
          for(let i=0; i<props.ingredients[ingredientName]; i++) {
          burgerIngredientElements.push(
          <BurgerIngredient type={ingredientName} />
          )
          }
          return [...burgerIngredientElements]


          Also, I don't think this code is doing what you think it's doing. You're pushing to an existing array, then spreading it's contents into another array. You're essentially just shallow-cloning. It might look rendered correctly (probably because JSX now does fragments) but the structure is questionable.





          Anyways, a more functional way to iterate from 0 to N is to create an array of N items (it doesn't matter what the values are) and operate on that array using array methods. One way this can be achieved is using Array and array.fill.



          Also, instead of a loop and an outer variable holding an array, you can use array.reduce with the accumulator being that array. That way, you don't have that extra mutable variable.



          Your code could look like this:



          function getBurgerIngredients() {
          const ingredients = props.ingredients

          return Object.keys(ingredients).reduce((c, ingredientName) => {
          const range = Array(ingredients[ingredientName]).fill()

          return [...c, ...range.map(() => (<BurgerIngredient type={ingredientName} />))]
          }, );
          }





          share|improve this answer












          const ingredientNames = Object.keys(props.ingredients);


          Just be aware that anything that iterates/enumerates an object's keys (Object.keys, for-in, etc.) does not guarantee order. So it might not always be "salad, cheese, cheese, meat, meat" in the end. It just happens that most browsers iterate in the order they were created/added to the object, which is why it appears like so. If you want order, use an array to begin with.



              let burgerIngredientElements = ;
          for(let i=0; i<props.ingredients[ingredientName]; i++) {
          burgerIngredientElements.push(
          <BurgerIngredient type={ingredientName} />
          )
          }
          return [...burgerIngredientElements]


          Also, I don't think this code is doing what you think it's doing. You're pushing to an existing array, then spreading it's contents into another array. You're essentially just shallow-cloning. It might look rendered correctly (probably because JSX now does fragments) but the structure is questionable.





          Anyways, a more functional way to iterate from 0 to N is to create an array of N items (it doesn't matter what the values are) and operate on that array using array methods. One way this can be achieved is using Array and array.fill.



          Also, instead of a loop and an outer variable holding an array, you can use array.reduce with the accumulator being that array. That way, you don't have that extra mutable variable.



          Your code could look like this:



          function getBurgerIngredients() {
          const ingredients = props.ingredients

          return Object.keys(ingredients).reduce((c, ingredientName) => {
          const range = Array(ingredients[ingredientName]).fill()

          return [...c, ...range.map(() => (<BurgerIngredient type={ingredientName} />))]
          }, );
          }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 19 at 16:41









          Joseph

          22.4k21835




          22.4k21835












          • Thanks, this helped a great deal (especially the part where you explain shallow-cloning) :)
            – dinika saxena
            Nov 19 at 18:11


















          • Thanks, this helped a great deal (especially the part where you explain shallow-cloning) :)
            – dinika saxena
            Nov 19 at 18:11
















          Thanks, this helped a great deal (especially the part where you explain shallow-cloning) :)
          – dinika saxena
          Nov 19 at 18:11




          Thanks, this helped a great deal (especially the part where you explain shallow-cloning) :)
          – dinika saxena
          Nov 19 at 18:11


















           

          draft saved


          draft discarded



















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f207976%2ftransform-a-javascript-object-to-an-array-based-on-value-of-each-key-in-the-orig%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Сан-Квентин

          8-я гвардейская общевойсковая армия

          Алькесар