Javascript seperating array of objects into multiple arrays using map(), and Iterator












2

















  1. Basically I have an array of objects like



    var array = [{x: 10, y: 5, r: 10, ...} ]




There are more fields in the object, but to the point, this is the way I've found to seperate the fields to arrays:



var x = array.map(obj => obj.x);
var y = array.map(obj => obj.y);
// and so on for each field


Works, but seems very inefficient as the number of fields and the array size grows, as this scans the array multiple times. I could use a standard loop, but I do prefer the map() as I think it is more readable in this case.
Is it possible to return multiple values from map?
I think something like:



var [x, y] = array.map(obj => [obj.x, obj.y]); // should output two arrays


Or anything similar which will be readable (reduce is less readable IMO).




  1. I did notice some newer javascript functions like array.entries() which return an iterator object. How can I implement such functions?










share|improve this question

























  • Do all the objects contain the same keys?

    – ibrahim mahrir
    Jan 2 at 18:16


















2

















  1. Basically I have an array of objects like



    var array = [{x: 10, y: 5, r: 10, ...} ]




There are more fields in the object, but to the point, this is the way I've found to seperate the fields to arrays:



var x = array.map(obj => obj.x);
var y = array.map(obj => obj.y);
// and so on for each field


Works, but seems very inefficient as the number of fields and the array size grows, as this scans the array multiple times. I could use a standard loop, but I do prefer the map() as I think it is more readable in this case.
Is it possible to return multiple values from map?
I think something like:



var [x, y] = array.map(obj => [obj.x, obj.y]); // should output two arrays


Or anything similar which will be readable (reduce is less readable IMO).




  1. I did notice some newer javascript functions like array.entries() which return an iterator object. How can I implement such functions?










share|improve this question

























  • Do all the objects contain the same keys?

    – ibrahim mahrir
    Jan 2 at 18:16
















2












2








2










  1. Basically I have an array of objects like



    var array = [{x: 10, y: 5, r: 10, ...} ]




There are more fields in the object, but to the point, this is the way I've found to seperate the fields to arrays:



var x = array.map(obj => obj.x);
var y = array.map(obj => obj.y);
// and so on for each field


Works, but seems very inefficient as the number of fields and the array size grows, as this scans the array multiple times. I could use a standard loop, but I do prefer the map() as I think it is more readable in this case.
Is it possible to return multiple values from map?
I think something like:



var [x, y] = array.map(obj => [obj.x, obj.y]); // should output two arrays


Or anything similar which will be readable (reduce is less readable IMO).




  1. I did notice some newer javascript functions like array.entries() which return an iterator object. How can I implement such functions?










share|improve this question


















  1. Basically I have an array of objects like



    var array = [{x: 10, y: 5, r: 10, ...} ]




There are more fields in the object, but to the point, this is the way I've found to seperate the fields to arrays:



var x = array.map(obj => obj.x);
var y = array.map(obj => obj.y);
// and so on for each field


Works, but seems very inefficient as the number of fields and the array size grows, as this scans the array multiple times. I could use a standard loop, but I do prefer the map() as I think it is more readable in this case.
Is it possible to return multiple values from map?
I think something like:



var [x, y] = array.map(obj => [obj.x, obj.y]); // should output two arrays


Or anything similar which will be readable (reduce is less readable IMO).




  1. I did notice some newer javascript functions like array.entries() which return an iterator object. How can I implement such functions?







javascript arrays array-map






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 2 at 21:32







user3599803

















asked Jan 2 at 18:06









user3599803user3599803

93831749




93831749













  • Do all the objects contain the same keys?

    – ibrahim mahrir
    Jan 2 at 18:16





















  • Do all the objects contain the same keys?

    – ibrahim mahrir
    Jan 2 at 18:16



















Do all the objects contain the same keys?

– ibrahim mahrir
Jan 2 at 18:16







Do all the objects contain the same keys?

– ibrahim mahrir
Jan 2 at 18:16














3 Answers
3






active

oldest

votes


















4














You could reduce the array and iterate the objects key/value pairs. Then push the values to the array of the given property.






var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }],
result = array.reduce((r, o) => {
Object.entries(o).forEach(([k, v]) => (r[k] = r[k] || ).push(v));
return r;
}, Object.create(null));

console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }








share|improve this answer































    1














    So, you were on to the right start with your second attempt:



    var [x, y] = array.map(obj => [obj.x, obj.y]);


    As you indicate, the first attempt is too inefficient, since you will have to loop through the array multiple times for each field you want to pull out, but you can do everything you want to do using an array's .reduce() method.



    I would do the following:



    var [x, y] = array.reduce(
    (accum, val) => {
    accum[0].push(val.x);
    accum[1].push(val.y);
    return accum;
    },
    [ , ]
    );


    What I'm doing is telling the reducer to initialize the accumulator with an empty array of arrays ([ , ]), and when it loops through the array, it will put the .x properties into the first array in the accumulator and the .y properties into the second array. And thanks to destructuring, x will be an array of all the .x properties and y will be an array of all the .y properties.



    This approach is easy to extend as your fields grow by adding more empty arrays to the initial accumulator object and making sure in the reducer to push those fields into that new object.






    share|improve this answer
























    • How to make it generic? i.e not just for two properties

      – user3599803
      Jan 2 at 21:33



















    0














    If all the objects have the same keys, you could get a copy of those keys and cache so you won't need to get them for every object. You can then use those keys to initialize the result object, then loop the array and push the values into the arrays, like so:



    var keys = Object.keys(array[0]);                          // get the keys of the first object (assuming all objects have the same keys)
    var result = {}; // the result object (you can use the safe Object.create(null) instead of {})

    keys.forEach(key => result[key] = ); // initialize the result object (make an empty array entry for each key in keys)

    array.forEach(obj => // for each object in array
    keys.forEach(key => result[key].push(obj[key])) // add the values of this object to their corresponding array from result using keys from the array keys
    );


    Demo:






    var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }];

    var keys = Object.keys(array[0]);
    var result = {};

    keys.forEach(key => result[key] = );

    array.forEach(obj =>
    keys.forEach(key => result[key].push(obj[key]))
    );

    console.log(result);








    share|improve this answer























      Your Answer






      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: "1"
      };
      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',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      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%2fstackoverflow.com%2fquestions%2f54011113%2fjavascript-seperating-array-of-objects-into-multiple-arrays-using-map-and-ite%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      4














      You could reduce the array and iterate the objects key/value pairs. Then push the values to the array of the given property.






      var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }],
      result = array.reduce((r, o) => {
      Object.entries(o).forEach(([k, v]) => (r[k] = r[k] || ).push(v));
      return r;
      }, Object.create(null));

      console.log(result);

      .as-console-wrapper { max-height: 100% !important; top: 0; }








      share|improve this answer




























        4














        You could reduce the array and iterate the objects key/value pairs. Then push the values to the array of the given property.






        var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }],
        result = array.reduce((r, o) => {
        Object.entries(o).forEach(([k, v]) => (r[k] = r[k] || ).push(v));
        return r;
        }, Object.create(null));

        console.log(result);

        .as-console-wrapper { max-height: 100% !important; top: 0; }








        share|improve this answer


























          4












          4








          4







          You could reduce the array and iterate the objects key/value pairs. Then push the values to the array of the given property.






          var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }],
          result = array.reduce((r, o) => {
          Object.entries(o).forEach(([k, v]) => (r[k] = r[k] || ).push(v));
          return r;
          }, Object.create(null));

          console.log(result);

          .as-console-wrapper { max-height: 100% !important; top: 0; }








          share|improve this answer













          You could reduce the array and iterate the objects key/value pairs. Then push the values to the array of the given property.






          var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }],
          result = array.reduce((r, o) => {
          Object.entries(o).forEach(([k, v]) => (r[k] = r[k] || ).push(v));
          return r;
          }, Object.create(null));

          console.log(result);

          .as-console-wrapper { max-height: 100% !important; top: 0; }








          var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }],
          result = array.reduce((r, o) => {
          Object.entries(o).forEach(([k, v]) => (r[k] = r[k] || ).push(v));
          return r;
          }, Object.create(null));

          console.log(result);

          .as-console-wrapper { max-height: 100% !important; top: 0; }





          var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }],
          result = array.reduce((r, o) => {
          Object.entries(o).forEach(([k, v]) => (r[k] = r[k] || ).push(v));
          return r;
          }, Object.create(null));

          console.log(result);

          .as-console-wrapper { max-height: 100% !important; top: 0; }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 2 at 18:11









          Nina ScholzNina Scholz

          191k15104176




          191k15104176

























              1














              So, you were on to the right start with your second attempt:



              var [x, y] = array.map(obj => [obj.x, obj.y]);


              As you indicate, the first attempt is too inefficient, since you will have to loop through the array multiple times for each field you want to pull out, but you can do everything you want to do using an array's .reduce() method.



              I would do the following:



              var [x, y] = array.reduce(
              (accum, val) => {
              accum[0].push(val.x);
              accum[1].push(val.y);
              return accum;
              },
              [ , ]
              );


              What I'm doing is telling the reducer to initialize the accumulator with an empty array of arrays ([ , ]), and when it loops through the array, it will put the .x properties into the first array in the accumulator and the .y properties into the second array. And thanks to destructuring, x will be an array of all the .x properties and y will be an array of all the .y properties.



              This approach is easy to extend as your fields grow by adding more empty arrays to the initial accumulator object and making sure in the reducer to push those fields into that new object.






              share|improve this answer
























              • How to make it generic? i.e not just for two properties

                – user3599803
                Jan 2 at 21:33
















              1














              So, you were on to the right start with your second attempt:



              var [x, y] = array.map(obj => [obj.x, obj.y]);


              As you indicate, the first attempt is too inefficient, since you will have to loop through the array multiple times for each field you want to pull out, but you can do everything you want to do using an array's .reduce() method.



              I would do the following:



              var [x, y] = array.reduce(
              (accum, val) => {
              accum[0].push(val.x);
              accum[1].push(val.y);
              return accum;
              },
              [ , ]
              );


              What I'm doing is telling the reducer to initialize the accumulator with an empty array of arrays ([ , ]), and when it loops through the array, it will put the .x properties into the first array in the accumulator and the .y properties into the second array. And thanks to destructuring, x will be an array of all the .x properties and y will be an array of all the .y properties.



              This approach is easy to extend as your fields grow by adding more empty arrays to the initial accumulator object and making sure in the reducer to push those fields into that new object.






              share|improve this answer
























              • How to make it generic? i.e not just for two properties

                – user3599803
                Jan 2 at 21:33














              1












              1








              1







              So, you were on to the right start with your second attempt:



              var [x, y] = array.map(obj => [obj.x, obj.y]);


              As you indicate, the first attempt is too inefficient, since you will have to loop through the array multiple times for each field you want to pull out, but you can do everything you want to do using an array's .reduce() method.



              I would do the following:



              var [x, y] = array.reduce(
              (accum, val) => {
              accum[0].push(val.x);
              accum[1].push(val.y);
              return accum;
              },
              [ , ]
              );


              What I'm doing is telling the reducer to initialize the accumulator with an empty array of arrays ([ , ]), and when it loops through the array, it will put the .x properties into the first array in the accumulator and the .y properties into the second array. And thanks to destructuring, x will be an array of all the .x properties and y will be an array of all the .y properties.



              This approach is easy to extend as your fields grow by adding more empty arrays to the initial accumulator object and making sure in the reducer to push those fields into that new object.






              share|improve this answer













              So, you were on to the right start with your second attempt:



              var [x, y] = array.map(obj => [obj.x, obj.y]);


              As you indicate, the first attempt is too inefficient, since you will have to loop through the array multiple times for each field you want to pull out, but you can do everything you want to do using an array's .reduce() method.



              I would do the following:



              var [x, y] = array.reduce(
              (accum, val) => {
              accum[0].push(val.x);
              accum[1].push(val.y);
              return accum;
              },
              [ , ]
              );


              What I'm doing is telling the reducer to initialize the accumulator with an empty array of arrays ([ , ]), and when it loops through the array, it will put the .x properties into the first array in the accumulator and the .y properties into the second array. And thanks to destructuring, x will be an array of all the .x properties and y will be an array of all the .y properties.



              This approach is easy to extend as your fields grow by adding more empty arrays to the initial accumulator object and making sure in the reducer to push those fields into that new object.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Jan 2 at 18:27









              Ryan DablerRyan Dabler

              17117




              17117













              • How to make it generic? i.e not just for two properties

                – user3599803
                Jan 2 at 21:33



















              • How to make it generic? i.e not just for two properties

                – user3599803
                Jan 2 at 21:33

















              How to make it generic? i.e not just for two properties

              – user3599803
              Jan 2 at 21:33





              How to make it generic? i.e not just for two properties

              – user3599803
              Jan 2 at 21:33











              0














              If all the objects have the same keys, you could get a copy of those keys and cache so you won't need to get them for every object. You can then use those keys to initialize the result object, then loop the array and push the values into the arrays, like so:



              var keys = Object.keys(array[0]);                          // get the keys of the first object (assuming all objects have the same keys)
              var result = {}; // the result object (you can use the safe Object.create(null) instead of {})

              keys.forEach(key => result[key] = ); // initialize the result object (make an empty array entry for each key in keys)

              array.forEach(obj => // for each object in array
              keys.forEach(key => result[key].push(obj[key])) // add the values of this object to their corresponding array from result using keys from the array keys
              );


              Demo:






              var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }];

              var keys = Object.keys(array[0]);
              var result = {};

              keys.forEach(key => result[key] = );

              array.forEach(obj =>
              keys.forEach(key => result[key].push(obj[key]))
              );

              console.log(result);








              share|improve this answer




























                0














                If all the objects have the same keys, you could get a copy of those keys and cache so you won't need to get them for every object. You can then use those keys to initialize the result object, then loop the array and push the values into the arrays, like so:



                var keys = Object.keys(array[0]);                          // get the keys of the first object (assuming all objects have the same keys)
                var result = {}; // the result object (you can use the safe Object.create(null) instead of {})

                keys.forEach(key => result[key] = ); // initialize the result object (make an empty array entry for each key in keys)

                array.forEach(obj => // for each object in array
                keys.forEach(key => result[key].push(obj[key])) // add the values of this object to their corresponding array from result using keys from the array keys
                );


                Demo:






                var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }];

                var keys = Object.keys(array[0]);
                var result = {};

                keys.forEach(key => result[key] = );

                array.forEach(obj =>
                keys.forEach(key => result[key].push(obj[key]))
                );

                console.log(result);








                share|improve this answer


























                  0












                  0








                  0







                  If all the objects have the same keys, you could get a copy of those keys and cache so you won't need to get them for every object. You can then use those keys to initialize the result object, then loop the array and push the values into the arrays, like so:



                  var keys = Object.keys(array[0]);                          // get the keys of the first object (assuming all objects have the same keys)
                  var result = {}; // the result object (you can use the safe Object.create(null) instead of {})

                  keys.forEach(key => result[key] = ); // initialize the result object (make an empty array entry for each key in keys)

                  array.forEach(obj => // for each object in array
                  keys.forEach(key => result[key].push(obj[key])) // add the values of this object to their corresponding array from result using keys from the array keys
                  );


                  Demo:






                  var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }];

                  var keys = Object.keys(array[0]);
                  var result = {};

                  keys.forEach(key => result[key] = );

                  array.forEach(obj =>
                  keys.forEach(key => result[key].push(obj[key]))
                  );

                  console.log(result);








                  share|improve this answer













                  If all the objects have the same keys, you could get a copy of those keys and cache so you won't need to get them for every object. You can then use those keys to initialize the result object, then loop the array and push the values into the arrays, like so:



                  var keys = Object.keys(array[0]);                          // get the keys of the first object (assuming all objects have the same keys)
                  var result = {}; // the result object (you can use the safe Object.create(null) instead of {})

                  keys.forEach(key => result[key] = ); // initialize the result object (make an empty array entry for each key in keys)

                  array.forEach(obj => // for each object in array
                  keys.forEach(key => result[key].push(obj[key])) // add the values of this object to their corresponding array from result using keys from the array keys
                  );


                  Demo:






                  var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }];

                  var keys = Object.keys(array[0]);
                  var result = {};

                  keys.forEach(key => result[key] = );

                  array.forEach(obj =>
                  keys.forEach(key => result[key].push(obj[key]))
                  );

                  console.log(result);








                  var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }];

                  var keys = Object.keys(array[0]);
                  var result = {};

                  keys.forEach(key => result[key] = );

                  array.forEach(obj =>
                  keys.forEach(key => result[key].push(obj[key]))
                  );

                  console.log(result);





                  var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }];

                  var keys = Object.keys(array[0]);
                  var result = {};

                  keys.forEach(key => result[key] = );

                  array.forEach(obj =>
                  keys.forEach(key => result[key].push(obj[key]))
                  );

                  console.log(result);






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 2 at 18:27









                  ibrahim mahriribrahim mahrir

                  22.2k41951




                  22.2k41951






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54011113%2fjavascript-seperating-array-of-objects-into-multiple-arrays-using-map-and-ite%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

                      Monofisismo

                      Angular Downloading a file using contenturl with Basic Authentication

                      Olmecas