1

I have tried to sort the javascript array which is having "order" as the key but it is sorting only the parent array and inner objects are not sorting

Here is my sample code which have tried,

Sample JSON response:

       var MainObj = [
      {
        "title": "Merchant2",
        "order": 2,
        "subMenu": [
          {
            "subMenu1": "Initiate2",
            "order": 2
          },
          {
            "subMenu2": "Initiate1",
            "order": 1
          }
        ]
      },
      {
        "title": "Merchant1",
        "order": 1,
        "subMenu": [
          {
            "subMenu1": "Initiate2",
            "order": 2
          },
          {
            "subMenu2": "Initiate1",
            "order": 1
          }
        ]
      }
    ]

And below is the sort functionality,

var MainObj = [{
    "title": "Merchant2",
    "order": 2,
    "subMenu": [{
        "subMenu1": "Initiate2",
        "order": 2
      },
      {
        "subMenu2": "Initiate1",
        "order": 1
      }
    ]
  },
  {
    "title": "Merchant1",
    "order": 1,
    "subMenu": [{
        "subMenu1": "Initiate2",
        "order": 2
      },
      {
        "subMenu2": "Initiate1",
        "order": 1
      }
    ]
  }
]

var sort = function(prop, arr) {
  prop = prop.split('.');
  var len = prop.length;

  arr.sort(function(a, b) {
    var i = 0;
    while (i < len) {
      a = a[prop[i]];
      b = b[prop[i]];
      i++;
    }
    if (a < b) {
      return -1;
    } else if (a > b) {
      return 1;
    } else {
      return 0;
    }
  });
  return arr;
};

console.log(sort('order', MainObj));

But the expected output should be in the below way,

    [
      {
        "title": "Merchant",
        "order": 1,
        "subMenu": [
          {
            "subMenu1": "Initiate1",
            "order": 1
          },
          {
            "subMenu1": "Initiate2",
            "order": 2
          },
          
        ]
      }
    ]
Nexo
  • 2,125
  • 2
  • 10
  • 20
vishnu
  • 4,377
  • 15
  • 52
  • 89

1 Answers1

4

You're not reaching into subMenu at all in your sort function. It's also unclear why you're splitting prop, and what the length has to do with anything, but based on your sample input and expected output, it can be much simpler:

// sort an array of objects based on the value of those objects' `prop`
// creates a new array with [...] because `sort` mutates. this could be changed
// to use partial application if you'll have the same logic for other properties
// in the future.
const sortByProp = (prop, xs) =>
  [...xs.sort((a, b) => a[prop] - b[prop])]

// sort the parent array based on some prop, and subMenu's array based on
// the same prop. if `subMenu` can possibly change down the line, that should be
// moved to an argument as well.
const sort = (prop, xs) =>
  sortByProp(prop, xs.map((x) => ({
    ...x,
    subMenu: sortByProp(prop, x.subMenu)
  })))

// test
console.log(
  JSON.stringify(
    sort('order', testInput), null, 2
  )
)
Zac Anger
  • 6,983
  • 2
  • 15
  • 42
  • `@Zac Anger` - Thanks, Your solution is working but forgot to mention that, sort should be applicable for all parent object also i.e, Now it's applying only for child elements. I have updated the sample input. can you please help on this. – vishnu Dec 31 '22 at 04:40
  • Sure, you can just use the same logic. I'll expand the answer. – Zac Anger Dec 31 '22 at 04:46
  • `@Zac Anger` - Thanks. Now it is perfect.. – vishnu Dec 31 '22 at 04:49
  • @ZacAnger +1 by my side – zain ul din Dec 31 '22 at 05:11
  • Can we optimize this function as currently its o(n^2)? – Nexo Dec 31 '22 at 21:34
  • 1
    @Nikkkshit it definitely could be optimized, though I would favor readability over optimization unless there's a known performance issue (like working with a particularly large response object). – Zac Anger Jan 01 '23 at 05:26