3

I have one array, which includes children. I have successfully sorted the array but unable to sort it, children.

Using the below code I am able to sort outer mail array elements but not its children.

https://jsfiddle.net/eokd5uzj/

var arry = [{
    'id': 301,
    'name': '2 Foo',
    'open': 'open',
    'children': [{
        'id': 1313,
        'name': '2.1 Foo ',
        'open': 'open'
      },
      {
        'id': 1143,
        'name': '2.3 Foo ',
        'open': 'open'
      },
      {
        'id': 1132,
        'name': '2.2 Foo ',
        'open': 'open'
      },
    ],
  },
  {
    'id': 30,
    'name': '1 Foo',
    'open': 'open',
    'children': [{
        'id': 1134,
        'name': '1.1 Foo ',
        'open': 'open'
      },
      {
        'id': 1130,
        'name': '1.3 Foo ',
        'open': 'open'
      },
      {
        'id': 1123,
        'name': '1.2 Foo ',
        'open': 'open'
      },
    ],
  },
];


function SortByName(a, b) {
  var aName = a.name.toLowerCase();
  var bName = b.name.toLowerCase();
  return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0));
}


$(document).ready(function() {
  var sorted_array = arry.sort(SortByName)
  console.log(sorted_array)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p id='data'>

</p>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
rahul.m
  • 5,572
  • 3
  • 23
  • 50

4 Answers4

4

You need to iterate the array as well for sorting all children. An assignment is not necessary, because Array#sort mutates the array.

array.forEach(({ children }) => children.sort(sortByName));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

Please modify your function as below

function SortByName(a, b){
 if(a.children){
   a.children = a.children.sort(SortByName)
  }
  if(b.children){
   b.children = b.children.sort(SortByName)
  }
  var aName = a.name.toLowerCase();
  var bName = b.name.toLowerCase();
  return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0));
}
Deepu
  • 198
  • 1
  • 8
  • 2
    Best solution so far! – Zuckerberg May 07 '20 at 07:49
  • 1
    @c.grey i didn't do anything... just called your function itself........ :) – Deepu May 07 '20 at 07:52
  • 1
    no, it's a worst solution, because the children are sorted for every parent element over and over. – Nina Scholz May 07 '20 at 07:53
  • @c.grey the complexity of the sorting witll be WAY higher by repeatedly sorting. Heck, based on the sorting algorithm implementation, you might get *the worst* complexity as algorithms like quicksort have worst performance on an already sorted dataset. Even if that's avoided, it's completely unnecessary to sort and re-sort the children. – VLAZ May 07 '20 at 08:17
  • @VLAZ do you have any optimal solution. – rahul.m May 07 '20 at 08:55
  • @c.grey [Nina's answer is very good](https://stackoverflow.com/a/61652330/) – VLAZ May 07 '20 at 10:19
0
var updated_sorted_array = sorted_array.map(function(arr){
  arr.children = arr.children.sort(SortByName);
  return arr;
})
Aman
  • 828
  • 1
  • 10
  • 15
0

you need 2 functions to sort these objects, one for Desc and one for Asc sort like this:

function sortByKeyDesc(array, key) {
    return array.sort(function (a, b) {
        var x = a[key]; var y = b[key];
        return ((x > y) ? -1 : ((x < y) ? 1 : 0));
    });
}
function sortByKeyAsc(array, key) {
    return array.sort(function (a, b) {
        var x = a[key]; var y = b[key];
        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
}

And when you want to sort your objects you can pass in the original collection and the Column that you need to sort based on like this:

  function querySucceeded(data) {
     posts = [];
     posts = sortByKeyDesc(data, "TagName");
  }
Makwana Prahlad
  • 1,025
  • 5
  • 20
  • You never need to implement two functions from scratch for sorting. To sort in reverse order, all you need is to negate the result of the correct order, so a generic `reverseSort = sortingFn => (...args) => -1 * sortingFn(...args)` works. Or you can make it more concrete by just flipping the arguments `reverseSort = fn => (a, b) => fn(a, b)`. If you have a functional utility library, you can just use a ready made solution `sortAsc = { /* ... logic ... */ }; sortDesc = flip(sortAsc);` This way you don't have to repeat yourself. – VLAZ May 07 '20 at 08:14