Sorting an array of categories and subcategories












2















Suppose we have and array of objects where each object represents a category or a subcategory, like this one:



var data = [
{type: "parent-category", order: 1, categoryId: 1},
{type: "parent-category", order: 2, categoryId: 2},
{type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
{type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
{type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
{type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
];


This array represent an example with two categories, where each one of they also have two subcategories.



Now, I'm facing with the problem of sort this array on some custom way. As you can note, the order attribute inside each object is related to the position (or ordering) of the object inside his level of hierarchy. And the relation between categories and subcategories is defined by the atributte parentCategoryId.



The expected sorting I need using as example the previous array of data should be this one:



var data = [
{type: "parent-category", order: 1, categoryId: 1},
{type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
{type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
{type: "parent-category", order: 2, categoryId: 2},
{type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2},
{type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2}
];


My current approach to solve this problem is based on creating a map to numbers, analyzing the values of the attributes with the following conditions:




  • For an object that has the type parent-category we assign the value of categoryId * 1000.

  • For an object that has the class child-category we assign the value of (parentCategoryId * 1000) + order


This logic is shown on the next sort implementation:






let data = [
{type: "parent-category", order: 1, categoryId: 1},
{type: "parent-category", order: 2, categoryId: 2},
{type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
{type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
{type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
{type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
];

let orderedData = data.sort((a, b) =>
{
var aCat = (a.type == "parent-category") ? a.categoryId : a.parentCategoryId;
var aOrder = (a.type == "parent-category") ? 0 : a.order;
var bCat = (b.type == "parent-category") ? b.categoryId : b.parentCategoryId;
var bOrder = (b.type == "parent-category") ? 0 : b.order;

return (aCat * 1000 + aOrder) - (bCat * 1000 + bOrder);
});

console.log(orderedData);





However, and ignoring the fact that the previous implementation works, my question is if there exists a better approach or alternative to solve this problem. I don't like the idea of depend on the mapping to numbers, because, for example, the previous implementation introduces a limitation on the numbers of subcategories (999 in this case) I can sort correctly under each category. Thanks!










share|improve this question





























    2















    Suppose we have and array of objects where each object represents a category or a subcategory, like this one:



    var data = [
    {type: "parent-category", order: 1, categoryId: 1},
    {type: "parent-category", order: 2, categoryId: 2},
    {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
    {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
    {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
    {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
    ];


    This array represent an example with two categories, where each one of they also have two subcategories.



    Now, I'm facing with the problem of sort this array on some custom way. As you can note, the order attribute inside each object is related to the position (or ordering) of the object inside his level of hierarchy. And the relation between categories and subcategories is defined by the atributte parentCategoryId.



    The expected sorting I need using as example the previous array of data should be this one:



    var data = [
    {type: "parent-category", order: 1, categoryId: 1},
    {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
    {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
    {type: "parent-category", order: 2, categoryId: 2},
    {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2},
    {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2}
    ];


    My current approach to solve this problem is based on creating a map to numbers, analyzing the values of the attributes with the following conditions:




    • For an object that has the type parent-category we assign the value of categoryId * 1000.

    • For an object that has the class child-category we assign the value of (parentCategoryId * 1000) + order


    This logic is shown on the next sort implementation:






    let data = [
    {type: "parent-category", order: 1, categoryId: 1},
    {type: "parent-category", order: 2, categoryId: 2},
    {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
    {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
    {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
    {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
    ];

    let orderedData = data.sort((a, b) =>
    {
    var aCat = (a.type == "parent-category") ? a.categoryId : a.parentCategoryId;
    var aOrder = (a.type == "parent-category") ? 0 : a.order;
    var bCat = (b.type == "parent-category") ? b.categoryId : b.parentCategoryId;
    var bOrder = (b.type == "parent-category") ? 0 : b.order;

    return (aCat * 1000 + aOrder) - (bCat * 1000 + bOrder);
    });

    console.log(orderedData);





    However, and ignoring the fact that the previous implementation works, my question is if there exists a better approach or alternative to solve this problem. I don't like the idea of depend on the mapping to numbers, because, for example, the previous implementation introduces a limitation on the numbers of subcategories (999 in this case) I can sort correctly under each category. Thanks!










    share|improve this question



























      2












      2








      2








      Suppose we have and array of objects where each object represents a category or a subcategory, like this one:



      var data = [
      {type: "parent-category", order: 1, categoryId: 1},
      {type: "parent-category", order: 2, categoryId: 2},
      {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
      {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
      {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
      {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
      ];


      This array represent an example with two categories, where each one of they also have two subcategories.



      Now, I'm facing with the problem of sort this array on some custom way. As you can note, the order attribute inside each object is related to the position (or ordering) of the object inside his level of hierarchy. And the relation between categories and subcategories is defined by the atributte parentCategoryId.



      The expected sorting I need using as example the previous array of data should be this one:



      var data = [
      {type: "parent-category", order: 1, categoryId: 1},
      {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
      {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
      {type: "parent-category", order: 2, categoryId: 2},
      {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2},
      {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2}
      ];


      My current approach to solve this problem is based on creating a map to numbers, analyzing the values of the attributes with the following conditions:




      • For an object that has the type parent-category we assign the value of categoryId * 1000.

      • For an object that has the class child-category we assign the value of (parentCategoryId * 1000) + order


      This logic is shown on the next sort implementation:






      let data = [
      {type: "parent-category", order: 1, categoryId: 1},
      {type: "parent-category", order: 2, categoryId: 2},
      {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
      {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
      {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
      {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
      ];

      let orderedData = data.sort((a, b) =>
      {
      var aCat = (a.type == "parent-category") ? a.categoryId : a.parentCategoryId;
      var aOrder = (a.type == "parent-category") ? 0 : a.order;
      var bCat = (b.type == "parent-category") ? b.categoryId : b.parentCategoryId;
      var bOrder = (b.type == "parent-category") ? 0 : b.order;

      return (aCat * 1000 + aOrder) - (bCat * 1000 + bOrder);
      });

      console.log(orderedData);





      However, and ignoring the fact that the previous implementation works, my question is if there exists a better approach or alternative to solve this problem. I don't like the idea of depend on the mapping to numbers, because, for example, the previous implementation introduces a limitation on the numbers of subcategories (999 in this case) I can sort correctly under each category. Thanks!










      share|improve this question
















      Suppose we have and array of objects where each object represents a category or a subcategory, like this one:



      var data = [
      {type: "parent-category", order: 1, categoryId: 1},
      {type: "parent-category", order: 2, categoryId: 2},
      {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
      {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
      {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
      {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
      ];


      This array represent an example with two categories, where each one of they also have two subcategories.



      Now, I'm facing with the problem of sort this array on some custom way. As you can note, the order attribute inside each object is related to the position (or ordering) of the object inside his level of hierarchy. And the relation between categories and subcategories is defined by the atributte parentCategoryId.



      The expected sorting I need using as example the previous array of data should be this one:



      var data = [
      {type: "parent-category", order: 1, categoryId: 1},
      {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
      {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
      {type: "parent-category", order: 2, categoryId: 2},
      {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2},
      {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2}
      ];


      My current approach to solve this problem is based on creating a map to numbers, analyzing the values of the attributes with the following conditions:




      • For an object that has the type parent-category we assign the value of categoryId * 1000.

      • For an object that has the class child-category we assign the value of (parentCategoryId * 1000) + order


      This logic is shown on the next sort implementation:






      let data = [
      {type: "parent-category", order: 1, categoryId: 1},
      {type: "parent-category", order: 2, categoryId: 2},
      {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
      {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
      {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
      {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
      ];

      let orderedData = data.sort((a, b) =>
      {
      var aCat = (a.type == "parent-category") ? a.categoryId : a.parentCategoryId;
      var aOrder = (a.type == "parent-category") ? 0 : a.order;
      var bCat = (b.type == "parent-category") ? b.categoryId : b.parentCategoryId;
      var bOrder = (b.type == "parent-category") ? 0 : b.order;

      return (aCat * 1000 + aOrder) - (bCat * 1000 + bOrder);
      });

      console.log(orderedData);





      However, and ignoring the fact that the previous implementation works, my question is if there exists a better approach or alternative to solve this problem. I don't like the idea of depend on the mapping to numbers, because, for example, the previous implementation introduces a limitation on the numbers of subcategories (999 in this case) I can sort correctly under each category. Thanks!






      let data = [
      {type: "parent-category", order: 1, categoryId: 1},
      {type: "parent-category", order: 2, categoryId: 2},
      {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
      {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
      {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
      {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
      ];

      let orderedData = data.sort((a, b) =>
      {
      var aCat = (a.type == "parent-category") ? a.categoryId : a.parentCategoryId;
      var aOrder = (a.type == "parent-category") ? 0 : a.order;
      var bCat = (b.type == "parent-category") ? b.categoryId : b.parentCategoryId;
      var bOrder = (b.type == "parent-category") ? 0 : b.order;

      return (aCat * 1000 + aOrder) - (bCat * 1000 + bOrder);
      });

      console.log(orderedData);





      let data = [
      {type: "parent-category", order: 1, categoryId: 1},
      {type: "parent-category", order: 2, categoryId: 2},
      {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
      {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
      {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
      {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
      ];

      let orderedData = data.sort((a, b) =>
      {
      var aCat = (a.type == "parent-category") ? a.categoryId : a.parentCategoryId;
      var aOrder = (a.type == "parent-category") ? 0 : a.order;
      var bCat = (b.type == "parent-category") ? b.categoryId : b.parentCategoryId;
      var bOrder = (b.type == "parent-category") ? 0 : b.order;

      return (aCat * 1000 + aOrder) - (bCat * 1000 + bOrder);
      });

      console.log(orderedData);






      javascript arrays sorting






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 4 at 4:36







      Shidersz

















      asked Jan 2 at 2:40









      ShiderszShidersz

      8,4302832




      8,4302832
























          4 Answers
          4






          active

          oldest

          votes


















          2














          Simple performant solution using Array#filter Array#sort and Array#map






          var data=[{type:"parent-category",order:1,categoryId:1},{type:"parent-category",order:2,categoryId:2},{type:"child-category",order:1,categoryId:3,parentCategoryId:1},{type:"child-category",order:2,categoryId:4,parentCategoryId:1},{type:"child-category",order:2,categoryId:5,parentCategoryId:2},{type:"child-category",order:1,categoryId:6,parentCategoryId:2}]

          let res = data
          .filter(({type}) => type === "parent-category")
          .sort((a,b) => a.order - b.order)
          .reduce((acc, curr) =>{
          const children = data
          .filter(({parentCategoryId}) => parentCategoryId === curr.categoryId)
          .sort((a,b) => a.order - b.order);

          acc.push(curr, ...children);
          return acc;
          }, );

          console.log(res);








          share|improve this answer


























          • This works also, thanks! I will give a better review tomorrow.

            – Shidersz
            Jan 2 at 4:06











          • @Shidersz check update

            – kemicofa
            Jan 2 at 4:09











          • Now, it is much better, I like this one. Just check that the current result has two arrays and I need only one.

            – Shidersz
            Jan 2 at 15:18











          • @Shidersz there you go. Check update.

            – kemicofa
            Jan 2 at 16:18






          • 1





            Ok, it is good now, I made some edits to move the reduce() in place of the map() making simplifications on the code, I hope you don't mind.

            – Shidersz
            Jan 2 at 16:43



















          2














          If performance is not an issue, I'd prefer using a more step-by-step way:






          /* ORIGINAL DATA */
          const data = [
          {type: "parent-category", order: 1, categoryId: 1},
          {type: "parent-category", order: 2, categoryId: 2},
          {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
          {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
          ];


          const sorted = ;
          const byOrder = (a, b) => a.order - b.order;

          // Get and sort parents first
          const parents = data.filter(obj => obj.type === 'parent-category');
          parents.sort(byOrder);

          // Push to resulting array by parent order
          parents.forEach(obj => {
          sorted.push(obj);

          // Get and sort corresponding children objs
          const children = data.filter(o => o.parentCategoryId === obj.categoryId);
          children.sort(byOrder);

          // Push the objs into resulting array together
          sorted.push.apply(sorted, children);
          });


          console.log(sorted);





          This approach involves more steps, but is straightforward and can be easily understood compared to your complex sorting logic.



          Using external libraries for only one function is overkill.






          share|improve this answer
























          • Good approach +1, thank you! However, I'm going to wait a little more just in case another answer comes.

            – Shidersz
            Jan 2 at 3:50



















          0














          For easy way, use lodash#orderBy





          If you don't prefer lodash, you can define your own specific function in sort



          I have not fully understand your sorting criteria, but, for example,



          function sort_categories(cat1,cat2) {
          if (cat1["order"] < cat2["order"])
          return -1;
          if (cat1["order"] > cat2["order"])
          return 1;
          return 0;
          }

          data.sort(sort_categories);


          will simply sort by orders.



          For details about return values, take a look at here




          If compareFunction is supplied, all non-undefined array elements are
          sorted according to the return value of the compare function (all
          undefined elements are sorted to the end of the array, with no call to
          compareFunction). If a and b are two elements being compared, then:




          • If compareFunction(a, b) is less than 0, sort a to an index lower than b (i.e. a comes first).


          • If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different
            elements. Note: the ECMAscript standard does not guarantee this
            behaviour, and thus not all browsers (e.g. Mozilla versions dating
            back to at least 2003) respect this.


          • If compareFunction(a, b) is greater than 0, sort b to an index lower than a (i.e. b comes first).


          • compareFunction(a, b) must always return the same value when given a specific pair of elements a and b as its two arguments. If
            inconsistent results are returned then the sort order is undefined.








          share|improve this answer
























          • I can't figure out an easy way of doing the sort with orderBy. You should note that categories have their order specified and subcategories too, but subcategories have to go (sorted) right after his parent category.

            – Shidersz
            Jan 2 at 3:54



















          0














          This will work. You sort your categoryId first and then do your math by running the forEach function.






          var data = [
          {type: "parent-category", order: 1, categoryId: 1},
          {type: "parent-category", order: 2, categoryId: 2},
          {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
          {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
          ];

          data.sort( function(a, b){
          return a.categoryId - b.categoryId;
          }).forEach( function(itm){
          itm.categoryId = itm.categoryId * 1000;
          if( itm.parentCategoryId){
          itm.parentCategoryId = itm.parentCategoryId * 1000 + itm.order
          }
          });

          console.log(data);





          Or in ES6 fashion...



          let orderedData = data.sort( (a, b) => {
          return a.categoryId - b.categoryId;
          }).forEach( itm => {
          itm.categoryId = itm.categoryId * 1000;
          if( itm.parentCategoryId){
          itm.parentCategoryId = itm.parentCategoryId * 1000 + itm.order
          }
          });





          share|improve this answer


























          • Please, check the expected output, this is not working as expected. Also, I don't want to change the values of the attributes, I just want to apply a custom order on the array of objects.

            – Shidersz
            Jan 2 at 15:26











          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%2f54000633%2fsorting-an-array-of-categories-and-subcategories%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          4 Answers
          4






          active

          oldest

          votes








          4 Answers
          4






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2














          Simple performant solution using Array#filter Array#sort and Array#map






          var data=[{type:"parent-category",order:1,categoryId:1},{type:"parent-category",order:2,categoryId:2},{type:"child-category",order:1,categoryId:3,parentCategoryId:1},{type:"child-category",order:2,categoryId:4,parentCategoryId:1},{type:"child-category",order:2,categoryId:5,parentCategoryId:2},{type:"child-category",order:1,categoryId:6,parentCategoryId:2}]

          let res = data
          .filter(({type}) => type === "parent-category")
          .sort((a,b) => a.order - b.order)
          .reduce((acc, curr) =>{
          const children = data
          .filter(({parentCategoryId}) => parentCategoryId === curr.categoryId)
          .sort((a,b) => a.order - b.order);

          acc.push(curr, ...children);
          return acc;
          }, );

          console.log(res);








          share|improve this answer


























          • This works also, thanks! I will give a better review tomorrow.

            – Shidersz
            Jan 2 at 4:06











          • @Shidersz check update

            – kemicofa
            Jan 2 at 4:09











          • Now, it is much better, I like this one. Just check that the current result has two arrays and I need only one.

            – Shidersz
            Jan 2 at 15:18











          • @Shidersz there you go. Check update.

            – kemicofa
            Jan 2 at 16:18






          • 1





            Ok, it is good now, I made some edits to move the reduce() in place of the map() making simplifications on the code, I hope you don't mind.

            – Shidersz
            Jan 2 at 16:43
















          2














          Simple performant solution using Array#filter Array#sort and Array#map






          var data=[{type:"parent-category",order:1,categoryId:1},{type:"parent-category",order:2,categoryId:2},{type:"child-category",order:1,categoryId:3,parentCategoryId:1},{type:"child-category",order:2,categoryId:4,parentCategoryId:1},{type:"child-category",order:2,categoryId:5,parentCategoryId:2},{type:"child-category",order:1,categoryId:6,parentCategoryId:2}]

          let res = data
          .filter(({type}) => type === "parent-category")
          .sort((a,b) => a.order - b.order)
          .reduce((acc, curr) =>{
          const children = data
          .filter(({parentCategoryId}) => parentCategoryId === curr.categoryId)
          .sort((a,b) => a.order - b.order);

          acc.push(curr, ...children);
          return acc;
          }, );

          console.log(res);








          share|improve this answer


























          • This works also, thanks! I will give a better review tomorrow.

            – Shidersz
            Jan 2 at 4:06











          • @Shidersz check update

            – kemicofa
            Jan 2 at 4:09











          • Now, it is much better, I like this one. Just check that the current result has two arrays and I need only one.

            – Shidersz
            Jan 2 at 15:18











          • @Shidersz there you go. Check update.

            – kemicofa
            Jan 2 at 16:18






          • 1





            Ok, it is good now, I made some edits to move the reduce() in place of the map() making simplifications on the code, I hope you don't mind.

            – Shidersz
            Jan 2 at 16:43














          2












          2








          2







          Simple performant solution using Array#filter Array#sort and Array#map






          var data=[{type:"parent-category",order:1,categoryId:1},{type:"parent-category",order:2,categoryId:2},{type:"child-category",order:1,categoryId:3,parentCategoryId:1},{type:"child-category",order:2,categoryId:4,parentCategoryId:1},{type:"child-category",order:2,categoryId:5,parentCategoryId:2},{type:"child-category",order:1,categoryId:6,parentCategoryId:2}]

          let res = data
          .filter(({type}) => type === "parent-category")
          .sort((a,b) => a.order - b.order)
          .reduce((acc, curr) =>{
          const children = data
          .filter(({parentCategoryId}) => parentCategoryId === curr.categoryId)
          .sort((a,b) => a.order - b.order);

          acc.push(curr, ...children);
          return acc;
          }, );

          console.log(res);








          share|improve this answer















          Simple performant solution using Array#filter Array#sort and Array#map






          var data=[{type:"parent-category",order:1,categoryId:1},{type:"parent-category",order:2,categoryId:2},{type:"child-category",order:1,categoryId:3,parentCategoryId:1},{type:"child-category",order:2,categoryId:4,parentCategoryId:1},{type:"child-category",order:2,categoryId:5,parentCategoryId:2},{type:"child-category",order:1,categoryId:6,parentCategoryId:2}]

          let res = data
          .filter(({type}) => type === "parent-category")
          .sort((a,b) => a.order - b.order)
          .reduce((acc, curr) =>{
          const children = data
          .filter(({parentCategoryId}) => parentCategoryId === curr.categoryId)
          .sort((a,b) => a.order - b.order);

          acc.push(curr, ...children);
          return acc;
          }, );

          console.log(res);








          var data=[{type:"parent-category",order:1,categoryId:1},{type:"parent-category",order:2,categoryId:2},{type:"child-category",order:1,categoryId:3,parentCategoryId:1},{type:"child-category",order:2,categoryId:4,parentCategoryId:1},{type:"child-category",order:2,categoryId:5,parentCategoryId:2},{type:"child-category",order:1,categoryId:6,parentCategoryId:2}]

          let res = data
          .filter(({type}) => type === "parent-category")
          .sort((a,b) => a.order - b.order)
          .reduce((acc, curr) =>{
          const children = data
          .filter(({parentCategoryId}) => parentCategoryId === curr.categoryId)
          .sort((a,b) => a.order - b.order);

          acc.push(curr, ...children);
          return acc;
          }, );

          console.log(res);





          var data=[{type:"parent-category",order:1,categoryId:1},{type:"parent-category",order:2,categoryId:2},{type:"child-category",order:1,categoryId:3,parentCategoryId:1},{type:"child-category",order:2,categoryId:4,parentCategoryId:1},{type:"child-category",order:2,categoryId:5,parentCategoryId:2},{type:"child-category",order:1,categoryId:6,parentCategoryId:2}]

          let res = data
          .filter(({type}) => type === "parent-category")
          .sort((a,b) => a.order - b.order)
          .reduce((acc, curr) =>{
          const children = data
          .filter(({parentCategoryId}) => parentCategoryId === curr.categoryId)
          .sort((a,b) => a.order - b.order);

          acc.push(curr, ...children);
          return acc;
          }, );

          console.log(res);






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 2 at 17:23

























          answered Jan 2 at 3:58









          kemicofakemicofa

          10.4k43983




          10.4k43983













          • This works also, thanks! I will give a better review tomorrow.

            – Shidersz
            Jan 2 at 4:06











          • @Shidersz check update

            – kemicofa
            Jan 2 at 4:09











          • Now, it is much better, I like this one. Just check that the current result has two arrays and I need only one.

            – Shidersz
            Jan 2 at 15:18











          • @Shidersz there you go. Check update.

            – kemicofa
            Jan 2 at 16:18






          • 1





            Ok, it is good now, I made some edits to move the reduce() in place of the map() making simplifications on the code, I hope you don't mind.

            – Shidersz
            Jan 2 at 16:43



















          • This works also, thanks! I will give a better review tomorrow.

            – Shidersz
            Jan 2 at 4:06











          • @Shidersz check update

            – kemicofa
            Jan 2 at 4:09











          • Now, it is much better, I like this one. Just check that the current result has two arrays and I need only one.

            – Shidersz
            Jan 2 at 15:18











          • @Shidersz there you go. Check update.

            – kemicofa
            Jan 2 at 16:18






          • 1





            Ok, it is good now, I made some edits to move the reduce() in place of the map() making simplifications on the code, I hope you don't mind.

            – Shidersz
            Jan 2 at 16:43

















          This works also, thanks! I will give a better review tomorrow.

          – Shidersz
          Jan 2 at 4:06





          This works also, thanks! I will give a better review tomorrow.

          – Shidersz
          Jan 2 at 4:06













          @Shidersz check update

          – kemicofa
          Jan 2 at 4:09





          @Shidersz check update

          – kemicofa
          Jan 2 at 4:09













          Now, it is much better, I like this one. Just check that the current result has two arrays and I need only one.

          – Shidersz
          Jan 2 at 15:18





          Now, it is much better, I like this one. Just check that the current result has two arrays and I need only one.

          – Shidersz
          Jan 2 at 15:18













          @Shidersz there you go. Check update.

          – kemicofa
          Jan 2 at 16:18





          @Shidersz there you go. Check update.

          – kemicofa
          Jan 2 at 16:18




          1




          1





          Ok, it is good now, I made some edits to move the reduce() in place of the map() making simplifications on the code, I hope you don't mind.

          – Shidersz
          Jan 2 at 16:43





          Ok, it is good now, I made some edits to move the reduce() in place of the map() making simplifications on the code, I hope you don't mind.

          – Shidersz
          Jan 2 at 16:43













          2














          If performance is not an issue, I'd prefer using a more step-by-step way:






          /* ORIGINAL DATA */
          const data = [
          {type: "parent-category", order: 1, categoryId: 1},
          {type: "parent-category", order: 2, categoryId: 2},
          {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
          {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
          ];


          const sorted = ;
          const byOrder = (a, b) => a.order - b.order;

          // Get and sort parents first
          const parents = data.filter(obj => obj.type === 'parent-category');
          parents.sort(byOrder);

          // Push to resulting array by parent order
          parents.forEach(obj => {
          sorted.push(obj);

          // Get and sort corresponding children objs
          const children = data.filter(o => o.parentCategoryId === obj.categoryId);
          children.sort(byOrder);

          // Push the objs into resulting array together
          sorted.push.apply(sorted, children);
          });


          console.log(sorted);





          This approach involves more steps, but is straightforward and can be easily understood compared to your complex sorting logic.



          Using external libraries for only one function is overkill.






          share|improve this answer
























          • Good approach +1, thank you! However, I'm going to wait a little more just in case another answer comes.

            – Shidersz
            Jan 2 at 3:50
















          2














          If performance is not an issue, I'd prefer using a more step-by-step way:






          /* ORIGINAL DATA */
          const data = [
          {type: "parent-category", order: 1, categoryId: 1},
          {type: "parent-category", order: 2, categoryId: 2},
          {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
          {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
          ];


          const sorted = ;
          const byOrder = (a, b) => a.order - b.order;

          // Get and sort parents first
          const parents = data.filter(obj => obj.type === 'parent-category');
          parents.sort(byOrder);

          // Push to resulting array by parent order
          parents.forEach(obj => {
          sorted.push(obj);

          // Get and sort corresponding children objs
          const children = data.filter(o => o.parentCategoryId === obj.categoryId);
          children.sort(byOrder);

          // Push the objs into resulting array together
          sorted.push.apply(sorted, children);
          });


          console.log(sorted);





          This approach involves more steps, but is straightforward and can be easily understood compared to your complex sorting logic.



          Using external libraries for only one function is overkill.






          share|improve this answer
























          • Good approach +1, thank you! However, I'm going to wait a little more just in case another answer comes.

            – Shidersz
            Jan 2 at 3:50














          2












          2








          2







          If performance is not an issue, I'd prefer using a more step-by-step way:






          /* ORIGINAL DATA */
          const data = [
          {type: "parent-category", order: 1, categoryId: 1},
          {type: "parent-category", order: 2, categoryId: 2},
          {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
          {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
          ];


          const sorted = ;
          const byOrder = (a, b) => a.order - b.order;

          // Get and sort parents first
          const parents = data.filter(obj => obj.type === 'parent-category');
          parents.sort(byOrder);

          // Push to resulting array by parent order
          parents.forEach(obj => {
          sorted.push(obj);

          // Get and sort corresponding children objs
          const children = data.filter(o => o.parentCategoryId === obj.categoryId);
          children.sort(byOrder);

          // Push the objs into resulting array together
          sorted.push.apply(sorted, children);
          });


          console.log(sorted);





          This approach involves more steps, but is straightforward and can be easily understood compared to your complex sorting logic.



          Using external libraries for only one function is overkill.






          share|improve this answer













          If performance is not an issue, I'd prefer using a more step-by-step way:






          /* ORIGINAL DATA */
          const data = [
          {type: "parent-category", order: 1, categoryId: 1},
          {type: "parent-category", order: 2, categoryId: 2},
          {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
          {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
          ];


          const sorted = ;
          const byOrder = (a, b) => a.order - b.order;

          // Get and sort parents first
          const parents = data.filter(obj => obj.type === 'parent-category');
          parents.sort(byOrder);

          // Push to resulting array by parent order
          parents.forEach(obj => {
          sorted.push(obj);

          // Get and sort corresponding children objs
          const children = data.filter(o => o.parentCategoryId === obj.categoryId);
          children.sort(byOrder);

          // Push the objs into resulting array together
          sorted.push.apply(sorted, children);
          });


          console.log(sorted);





          This approach involves more steps, but is straightforward and can be easily understood compared to your complex sorting logic.



          Using external libraries for only one function is overkill.






          /* ORIGINAL DATA */
          const data = [
          {type: "parent-category", order: 1, categoryId: 1},
          {type: "parent-category", order: 2, categoryId: 2},
          {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
          {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
          ];


          const sorted = ;
          const byOrder = (a, b) => a.order - b.order;

          // Get and sort parents first
          const parents = data.filter(obj => obj.type === 'parent-category');
          parents.sort(byOrder);

          // Push to resulting array by parent order
          parents.forEach(obj => {
          sorted.push(obj);

          // Get and sort corresponding children objs
          const children = data.filter(o => o.parentCategoryId === obj.categoryId);
          children.sort(byOrder);

          // Push the objs into resulting array together
          sorted.push.apply(sorted, children);
          });


          console.log(sorted);





          /* ORIGINAL DATA */
          const data = [
          {type: "parent-category", order: 1, categoryId: 1},
          {type: "parent-category", order: 2, categoryId: 2},
          {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
          {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
          ];


          const sorted = ;
          const byOrder = (a, b) => a.order - b.order;

          // Get and sort parents first
          const parents = data.filter(obj => obj.type === 'parent-category');
          parents.sort(byOrder);

          // Push to resulting array by parent order
          parents.forEach(obj => {
          sorted.push(obj);

          // Get and sort corresponding children objs
          const children = data.filter(o => o.parentCategoryId === obj.categoryId);
          children.sort(byOrder);

          // Push the objs into resulting array together
          sorted.push.apply(sorted, children);
          });


          console.log(sorted);






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 2 at 3:41









          Yong QuanYong Quan

          2,7872927




          2,7872927













          • Good approach +1, thank you! However, I'm going to wait a little more just in case another answer comes.

            – Shidersz
            Jan 2 at 3:50



















          • Good approach +1, thank you! However, I'm going to wait a little more just in case another answer comes.

            – Shidersz
            Jan 2 at 3:50

















          Good approach +1, thank you! However, I'm going to wait a little more just in case another answer comes.

          – Shidersz
          Jan 2 at 3:50





          Good approach +1, thank you! However, I'm going to wait a little more just in case another answer comes.

          – Shidersz
          Jan 2 at 3:50











          0














          For easy way, use lodash#orderBy





          If you don't prefer lodash, you can define your own specific function in sort



          I have not fully understand your sorting criteria, but, for example,



          function sort_categories(cat1,cat2) {
          if (cat1["order"] < cat2["order"])
          return -1;
          if (cat1["order"] > cat2["order"])
          return 1;
          return 0;
          }

          data.sort(sort_categories);


          will simply sort by orders.



          For details about return values, take a look at here




          If compareFunction is supplied, all non-undefined array elements are
          sorted according to the return value of the compare function (all
          undefined elements are sorted to the end of the array, with no call to
          compareFunction). If a and b are two elements being compared, then:




          • If compareFunction(a, b) is less than 0, sort a to an index lower than b (i.e. a comes first).


          • If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different
            elements. Note: the ECMAscript standard does not guarantee this
            behaviour, and thus not all browsers (e.g. Mozilla versions dating
            back to at least 2003) respect this.


          • If compareFunction(a, b) is greater than 0, sort b to an index lower than a (i.e. b comes first).


          • compareFunction(a, b) must always return the same value when given a specific pair of elements a and b as its two arguments. If
            inconsistent results are returned then the sort order is undefined.








          share|improve this answer
























          • I can't figure out an easy way of doing the sort with orderBy. You should note that categories have their order specified and subcategories too, but subcategories have to go (sorted) right after his parent category.

            – Shidersz
            Jan 2 at 3:54
















          0














          For easy way, use lodash#orderBy





          If you don't prefer lodash, you can define your own specific function in sort



          I have not fully understand your sorting criteria, but, for example,



          function sort_categories(cat1,cat2) {
          if (cat1["order"] < cat2["order"])
          return -1;
          if (cat1["order"] > cat2["order"])
          return 1;
          return 0;
          }

          data.sort(sort_categories);


          will simply sort by orders.



          For details about return values, take a look at here




          If compareFunction is supplied, all non-undefined array elements are
          sorted according to the return value of the compare function (all
          undefined elements are sorted to the end of the array, with no call to
          compareFunction). If a and b are two elements being compared, then:




          • If compareFunction(a, b) is less than 0, sort a to an index lower than b (i.e. a comes first).


          • If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different
            elements. Note: the ECMAscript standard does not guarantee this
            behaviour, and thus not all browsers (e.g. Mozilla versions dating
            back to at least 2003) respect this.


          • If compareFunction(a, b) is greater than 0, sort b to an index lower than a (i.e. b comes first).


          • compareFunction(a, b) must always return the same value when given a specific pair of elements a and b as its two arguments. If
            inconsistent results are returned then the sort order is undefined.








          share|improve this answer
























          • I can't figure out an easy way of doing the sort with orderBy. You should note that categories have their order specified and subcategories too, but subcategories have to go (sorted) right after his parent category.

            – Shidersz
            Jan 2 at 3:54














          0












          0








          0







          For easy way, use lodash#orderBy





          If you don't prefer lodash, you can define your own specific function in sort



          I have not fully understand your sorting criteria, but, for example,



          function sort_categories(cat1,cat2) {
          if (cat1["order"] < cat2["order"])
          return -1;
          if (cat1["order"] > cat2["order"])
          return 1;
          return 0;
          }

          data.sort(sort_categories);


          will simply sort by orders.



          For details about return values, take a look at here




          If compareFunction is supplied, all non-undefined array elements are
          sorted according to the return value of the compare function (all
          undefined elements are sorted to the end of the array, with no call to
          compareFunction). If a and b are two elements being compared, then:




          • If compareFunction(a, b) is less than 0, sort a to an index lower than b (i.e. a comes first).


          • If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different
            elements. Note: the ECMAscript standard does not guarantee this
            behaviour, and thus not all browsers (e.g. Mozilla versions dating
            back to at least 2003) respect this.


          • If compareFunction(a, b) is greater than 0, sort b to an index lower than a (i.e. b comes first).


          • compareFunction(a, b) must always return the same value when given a specific pair of elements a and b as its two arguments. If
            inconsistent results are returned then the sort order is undefined.








          share|improve this answer













          For easy way, use lodash#orderBy





          If you don't prefer lodash, you can define your own specific function in sort



          I have not fully understand your sorting criteria, but, for example,



          function sort_categories(cat1,cat2) {
          if (cat1["order"] < cat2["order"])
          return -1;
          if (cat1["order"] > cat2["order"])
          return 1;
          return 0;
          }

          data.sort(sort_categories);


          will simply sort by orders.



          For details about return values, take a look at here




          If compareFunction is supplied, all non-undefined array elements are
          sorted according to the return value of the compare function (all
          undefined elements are sorted to the end of the array, with no call to
          compareFunction). If a and b are two elements being compared, then:




          • If compareFunction(a, b) is less than 0, sort a to an index lower than b (i.e. a comes first).


          • If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different
            elements. Note: the ECMAscript standard does not guarantee this
            behaviour, and thus not all browsers (e.g. Mozilla versions dating
            back to at least 2003) respect this.


          • If compareFunction(a, b) is greater than 0, sort b to an index lower than a (i.e. b comes first).


          • compareFunction(a, b) must always return the same value when given a specific pair of elements a and b as its two arguments. If
            inconsistent results are returned then the sort order is undefined.









          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 2 at 3:23









          user3790180user3790180

          10819




          10819













          • I can't figure out an easy way of doing the sort with orderBy. You should note that categories have their order specified and subcategories too, but subcategories have to go (sorted) right after his parent category.

            – Shidersz
            Jan 2 at 3:54



















          • I can't figure out an easy way of doing the sort with orderBy. You should note that categories have their order specified and subcategories too, but subcategories have to go (sorted) right after his parent category.

            – Shidersz
            Jan 2 at 3:54

















          I can't figure out an easy way of doing the sort with orderBy. You should note that categories have their order specified and subcategories too, but subcategories have to go (sorted) right after his parent category.

          – Shidersz
          Jan 2 at 3:54





          I can't figure out an easy way of doing the sort with orderBy. You should note that categories have their order specified and subcategories too, but subcategories have to go (sorted) right after his parent category.

          – Shidersz
          Jan 2 at 3:54











          0














          This will work. You sort your categoryId first and then do your math by running the forEach function.






          var data = [
          {type: "parent-category", order: 1, categoryId: 1},
          {type: "parent-category", order: 2, categoryId: 2},
          {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
          {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
          ];

          data.sort( function(a, b){
          return a.categoryId - b.categoryId;
          }).forEach( function(itm){
          itm.categoryId = itm.categoryId * 1000;
          if( itm.parentCategoryId){
          itm.parentCategoryId = itm.parentCategoryId * 1000 + itm.order
          }
          });

          console.log(data);





          Or in ES6 fashion...



          let orderedData = data.sort( (a, b) => {
          return a.categoryId - b.categoryId;
          }).forEach( itm => {
          itm.categoryId = itm.categoryId * 1000;
          if( itm.parentCategoryId){
          itm.parentCategoryId = itm.parentCategoryId * 1000 + itm.order
          }
          });





          share|improve this answer


























          • Please, check the expected output, this is not working as expected. Also, I don't want to change the values of the attributes, I just want to apply a custom order on the array of objects.

            – Shidersz
            Jan 2 at 15:26
















          0














          This will work. You sort your categoryId first and then do your math by running the forEach function.






          var data = [
          {type: "parent-category", order: 1, categoryId: 1},
          {type: "parent-category", order: 2, categoryId: 2},
          {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
          {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
          ];

          data.sort( function(a, b){
          return a.categoryId - b.categoryId;
          }).forEach( function(itm){
          itm.categoryId = itm.categoryId * 1000;
          if( itm.parentCategoryId){
          itm.parentCategoryId = itm.parentCategoryId * 1000 + itm.order
          }
          });

          console.log(data);





          Or in ES6 fashion...



          let orderedData = data.sort( (a, b) => {
          return a.categoryId - b.categoryId;
          }).forEach( itm => {
          itm.categoryId = itm.categoryId * 1000;
          if( itm.parentCategoryId){
          itm.parentCategoryId = itm.parentCategoryId * 1000 + itm.order
          }
          });





          share|improve this answer


























          • Please, check the expected output, this is not working as expected. Also, I don't want to change the values of the attributes, I just want to apply a custom order on the array of objects.

            – Shidersz
            Jan 2 at 15:26














          0












          0








          0







          This will work. You sort your categoryId first and then do your math by running the forEach function.






          var data = [
          {type: "parent-category", order: 1, categoryId: 1},
          {type: "parent-category", order: 2, categoryId: 2},
          {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
          {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
          ];

          data.sort( function(a, b){
          return a.categoryId - b.categoryId;
          }).forEach( function(itm){
          itm.categoryId = itm.categoryId * 1000;
          if( itm.parentCategoryId){
          itm.parentCategoryId = itm.parentCategoryId * 1000 + itm.order
          }
          });

          console.log(data);





          Or in ES6 fashion...



          let orderedData = data.sort( (a, b) => {
          return a.categoryId - b.categoryId;
          }).forEach( itm => {
          itm.categoryId = itm.categoryId * 1000;
          if( itm.parentCategoryId){
          itm.parentCategoryId = itm.parentCategoryId * 1000 + itm.order
          }
          });





          share|improve this answer















          This will work. You sort your categoryId first and then do your math by running the forEach function.






          var data = [
          {type: "parent-category", order: 1, categoryId: 1},
          {type: "parent-category", order: 2, categoryId: 2},
          {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
          {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
          ];

          data.sort( function(a, b){
          return a.categoryId - b.categoryId;
          }).forEach( function(itm){
          itm.categoryId = itm.categoryId * 1000;
          if( itm.parentCategoryId){
          itm.parentCategoryId = itm.parentCategoryId * 1000 + itm.order
          }
          });

          console.log(data);





          Or in ES6 fashion...



          let orderedData = data.sort( (a, b) => {
          return a.categoryId - b.categoryId;
          }).forEach( itm => {
          itm.categoryId = itm.categoryId * 1000;
          if( itm.parentCategoryId){
          itm.parentCategoryId = itm.parentCategoryId * 1000 + itm.order
          }
          });





          var data = [
          {type: "parent-category", order: 1, categoryId: 1},
          {type: "parent-category", order: 2, categoryId: 2},
          {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
          {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
          ];

          data.sort( function(a, b){
          return a.categoryId - b.categoryId;
          }).forEach( function(itm){
          itm.categoryId = itm.categoryId * 1000;
          if( itm.parentCategoryId){
          itm.parentCategoryId = itm.parentCategoryId * 1000 + itm.order
          }
          });

          console.log(data);





          var data = [
          {type: "parent-category", order: 1, categoryId: 1},
          {type: "parent-category", order: 2, categoryId: 2},
          {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
          {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
          {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
          ];

          data.sort( function(a, b){
          return a.categoryId - b.categoryId;
          }).forEach( function(itm){
          itm.categoryId = itm.categoryId * 1000;
          if( itm.parentCategoryId){
          itm.parentCategoryId = itm.parentCategoryId * 1000 + itm.order
          }
          });

          console.log(data);






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 2 at 15:23









          Shidersz

          8,4302832




          8,4302832










          answered Jan 2 at 4:24









          andre mcgruderandre mcgruder

          1,022188




          1,022188













          • Please, check the expected output, this is not working as expected. Also, I don't want to change the values of the attributes, I just want to apply a custom order on the array of objects.

            – Shidersz
            Jan 2 at 15:26



















          • Please, check the expected output, this is not working as expected. Also, I don't want to change the values of the attributes, I just want to apply a custom order on the array of objects.

            – Shidersz
            Jan 2 at 15:26

















          Please, check the expected output, this is not working as expected. Also, I don't want to change the values of the attributes, I just want to apply a custom order on the array of objects.

          – Shidersz
          Jan 2 at 15:26





          Please, check the expected output, this is not working as expected. Also, I don't want to change the values of the attributes, I just want to apply a custom order on the array of objects.

          – Shidersz
          Jan 2 at 15:26


















          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%2f54000633%2fsorting-an-array-of-categories-and-subcategories%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