diff --git a/test/collections.js b/test/collections.js index 4bce6668e..4036d1fd2 100644 --- a/test/collections.js +++ b/test/collections.js @@ -496,6 +496,33 @@ list = ['q', 'w', 'e', 'r', 't', 'y']; deepEqual(_.sortBy(list), ['e', 'q', 'r', 't', 'w', 'y'], 'uses _.identity if iterator is not specified'); + + var smallCollection = _.shuffle(_.map(collection.slice(2, 7), function(pair) { + return {x: pair.x, y: pair.y}; + })); + sorted = [{x: 1, y: 3}, {x: 1, y: 4}, {x: 1, y: 5}, {x: 1, y: 6}, {x: 2, y: 1}]; + + deepEqual(_.sortBy(smallCollection, function(pair) { + return [pair.x, pair.y]; + }), sorted, 'Returning an array will sort by precedence'); + + deepEqual(_.sortBy(smallCollection, function(pair) { + return [pair.y, pair.x]; + }), _.sortBy(smallCollection, 'y')); + + smallCollection = _.shuffle([{a: 1, b: 2}, {a: 1}, {a: 1, b: 3}, {a: 2, b: -1}, {b: 5}]); + + deepEqual(_.sortBy([{a: 2}, {a: 2, b: 2}, {a: 2, b: undefined}], function(x) { + return 'b' in x ? [x.a, x.b] : [x.a]; + }), [{a: 2}, {a: 2, b: 2}, {a: 2, b: undefined}], 'array of longer length more important'); + + deepEqual(_.sortBy([{a: 2}, {a: 1, b: 2}], function(x) { + return 'b' in x ? [x.a, x.b] : [x.a]; + }), [{a: 1, b: 2}, {a: 2}], 'precedence more important than length'); + + deepEqual(_.sortBy(smallCollection, function(x) { + return [x.a, x.b]; + }), [{a: 1, b: 2}, {a: 1, b: 3}, {a: 1}, {a: 2, b: -1}, {b: 5}]); }); test('groupBy', function() { diff --git a/underscore.js b/underscore.js index 130b917aa..f2bfa7782 100644 --- a/underscore.js +++ b/underscore.js @@ -358,13 +358,19 @@ criteria: iterator(value, index, list) }; }).sort(function(left, right) { - var a = left.criteria; - var b = right.criteria; - if (a !== b) { - if (a > b || a === void 0) return 1; - if (a < b || b === void 0) return -1; + var leftArr = left.criteria; + var rightArr = right.criteria; + leftArr = _.isArray(leftArr) ? leftArr : [leftArr]; + rightArr = _.isArray(rightArr) ? rightArr : [rightArr]; + for (var i = 0, len = leftArr.length, blen = rightArr.length; i < len; i++) { + if (i >= blen) return 1; + var a = leftArr[i], b = rightArr[i]; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } } - return left.index - right.index; + return blen == len ? left.index - right.index : -1; }), 'value'); };