简体   繁体   中英

JS sort not sorting when given undefined

I can't figure out why the sort function doesn't sort the array containing undefined.

var sortBy = function(collection, iterator) {
    var newArr = map(collection, function(item, key, collection) {

        if (item === undefined, null) {
            return [undefined, undefined];

        } else {
            if (typeof(iterator) === 'string') {
                return [item, item[iterator]];

            } else {
                var results = iterator(item);
                return [item, results];
            }
        }
    });

    newArr.sort(function(a, b) { 
        return a[1] - b[1];
    });

    return map(newArr, function(item, key, collection) {
        return  item[0];
    });
};

var list = [4, 1, undefined, 3, 2];
sortBy(list, function(i) { return i; });

If i remove the undefined, the array sorts just fine. With it, it doesn't sort at all. Thanks for your help! (PS I'm new to coding so any other tips/recs on this are welcome)

Presuming the map function is something like:

function map(obj, fn) {
  var re = /^\d+$/;
  var arr = [];

  for (var p in obj) {
    if (re.test(p) && obj.hasOwnProperty(p)) {
      arr.push(fn(obj[p], p, obj)); 
    }
  }
  return arr;
}

then in the sort function, the statement:

return a[1] - b[1];

will do things like:

4 - undefined => NaN

So the erroneous line in the iterator could be:

    if (item === undefined || item === null) {
        return [undefined, 0];
    }

or whatever value you wish undefined and null to be sorted using— Infinity perhaps?

 if (item === undefined, null) 

does never fulfill - it's using the comma operator . You want if (item == null) , which will test for both undefined and null .

However, since your iterator in the example is the identity function, this bug does not matter and newArr looks as expected.


 return a[1] - b[1]; 

If one of the values is undefined , the result of the subtraction will be NaN - which is not a valid return value for a compare function. If such happens, the sort behavior is unspecified - it could be (implementation-dependent) anything from screwing up the order, not sorting at all or even never terminate. See also this answer and the relevant spec section .

So choose where you want to place undefined values in the result array, and put a comparable value for the desired position in your tuple (array). Maybe Infinity or -Infinity ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM