Search code examples
javascriptsortinglogic

How to push undefined or null to the back of an array with sort?


I have 3 items in an array and each of those items have a property called distanceFromUser which is just a number. Two of those objects have undefined for that property.

If I run items.sort((a,b) => a.distanceFromUser - b.distanceFromUser); the two object with undefined or null get put first in the array. How can I get them to go in the back of the array?


Solution

  • You could check the values for undefined or null and sort them to the end of the array, while perserving the order of the distance with a chained approach.

    var items = [{ id: 1, distanceFromUser: undefined }, { id: 2, distanceFromUser: 1 }, { id: 3, distanceFromUser: 2 }, { id: 4, distanceFromUser: 5 }, { id: 5, distanceFromUser: 1 }, { id: 6, distanceFromUser: undefined }, { id: 7, distanceFromUser: null }, { id: 8, distanceFromUser: null }];
    
    items.sort(
        (a, b) => 
            (a.distanceFromUser === undefined || a.distanceFromUser === null) -
            (b.distanceFromUser === undefined || b.distanceFromUser === null) ||
            a.distanceFromUser - b.distanceFromUser
    );
    
    console.log(items);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    A slightly shorter approach with Number.isFinite (does not convert to Number in advance as isFinite is doing).

    var items = [{ id: 1, distanceFromUser: undefined }, { id: 2, distanceFromUser: 1 }, { id: 3, distanceFromUser: 2 }, { id: 4, distanceFromUser: 5 }, { id: 5, distanceFromUser: 1 }, { id: 6, distanceFromUser: undefined }, { id: 7, distanceFromUser: null }, { id: 8, distanceFromUser: null }];
    
    items.sort(
        (a, b) => 
            !Number.isFinite(a.distanceFromUser) - !Number.isFinite(b.distanceFromUser) ||
            a.distanceFromUser - b.distanceFromUser
    );
    
    console.log(items);
    .as-console-wrapper { max-height: 100% !important; top: 0; }