-1

I have this object:

  [ {'id': 3, 'count': 9}, {'id': 4,'count': null}, {'id':5,'count':4}]

Basically, the order should be count but if count is null, the item(s) should be placed to the bottom of the sort. I tried the following but it is not working. The above should give (for asc):

  {'id': 3, 'count': 9}
  {'id':5,'count':4}
  {'id': 4,'count': null}

When descending:

  {'id': 5, 'count': 4}
  {'id':3,'count':9}
  {'id': 4,'count': null}

Code

let sortValue = -1; //asc
let direction = 'asc';

if (direction != "asc") {
  sortValue = 1;
}

objArr.sort(function(a: Item, b: Item) {

      const aCount  = a['count'] ;
      const bCount  = b['count'];

      if ( aCount == null){
        return -1;
      }

      if ( bCount == null){
        return -1;
      }

      return aCount>bCount? -1 * sortValue : aCount<bCount ? sortValue : 0;
Nie Selam
  • 1,343
  • 2
  • 24
  • 56
  • you return `-1` regardless of which number is null? – Bravo Oct 07 '19 at 08:24
  • hey @Bravo that was how I understood pushing them to the bottom can be achieved. But basically, if a count is null, the item should be at the bottom. Basically all items with count null should be placed at the bottom of the list. I assumed returning -1 would push the item to go down in the list i guess i am wrong – Nie Selam Oct 07 '19 at 08:29
  • you've tagged this question javascript but the code you pasted looks like typescript – codebox Oct 07 '19 at 08:30
  • please add thg results of sorting for *asc* and *desc*. where should `null` go in this cases? – Nina Scholz Oct 07 '19 at 08:33
  • I think the fact that you are returning -1 regardless of whether aCount or bCount is null is breaking the sort. How can the algorithm move nulls to the bottom if the function returns the same value regardless of whether null is the first or the second value? – codebox Oct 07 '19 at 08:42
  • @NinaScholz: see my update. But regardless of asc or desc, all count==null items should be at the bottom of the sort. – Nie Selam Oct 07 '19 at 08:44
  • btw, your *asc* sort violates the usual understanding of ascending and your *desc* as well. usually if the smaller value is at top and the greater value is at the bottom, this order is calles ascending, as the value grows over the following items. – Nina Scholz Oct 07 '19 at 08:48

3 Answers3

4

If you always want a null value to be at the bottom then return 1 when a is null and -1 when b is null.

function sort(array, sortValue) {
    return array.sort(function ({ count: a }, { count: b }) {
        if (a === null) return 1;
        if (b === null) return -1;
        return (b - a) * sortValue;
    });
}

var array = [{ id: 3, count: 9 }, { id: 4, count: null }, { id: 5, count: 4 }];

console.log(sort(array, -1));
console.log(sort(array, 1));
nick zoum
  • 7,216
  • 7
  • 36
  • 80
1

You could check for null and take the result of the check as sort order.

function sort(array, order = 'asc') {
    var factor = order === 'desc' || -1;
    return array.sort(({ count: a }, { count: b }) => 
        (a === null) - (b === null) || // move null to bottom
        factor * (a - b)               // sort by numerical value
    );
}

var array = [{ id: 3, count: 9 }, { id: 4, count: null }, { id: 5, count: 4 }];

console.log(sort(array));
console.log(sort(array, 'desc'));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

You need to define all the cases for return values -1, 0 and 1 in order for the .sort() to work properly:

let direction = 'asc';

objArr.sort((a, b) => {

  if (a.count === null && b.count === null) {
    return 0;
  }

  if (a.count === null) {
    return 1;
  }

  if (b.count=== null) {
    return -1;
  }

  // Ascending direction
  if (direction === 'asc') {
    return a.count - b.count;
  }

  // Descending direction
  return b.count - a.count;
}
micnic
  • 10,915
  • 5
  • 44
  • 55