mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-08 18:17:48 +00:00
Ensure _.sortBy performs a stable sort. [closes #59]
Former-commit-id: 09c5ff85ef0f1d054579ec4260a7f76d9c0da281
This commit is contained in:
@@ -151,6 +151,7 @@
|
|||||||
'head',
|
'head',
|
||||||
'identity',
|
'identity',
|
||||||
'include',
|
'include',
|
||||||
|
'index',
|
||||||
'indexOf',
|
'indexOf',
|
||||||
'initial',
|
'initial',
|
||||||
'inject',
|
'inject',
|
||||||
@@ -304,7 +305,7 @@
|
|||||||
|
|
||||||
// minify internal properties used by 'compareAscending', `_.clone`, `_.merge`, and `_.sortBy`
|
// minify internal properties used by 'compareAscending', `_.clone`, `_.merge`, and `_.sortBy`
|
||||||
(function() {
|
(function() {
|
||||||
var properties = ['criteria', 'source', 'value'],
|
var properties = ['criteria', 'index', 'source', 'value'],
|
||||||
snippets = source.match(/( +)(?:function clone|function compareAscending|var merge|var sortBy)\b[\s\S]+?\n\1}/g);
|
snippets = source.match(/( +)(?:function clone|function compareAscending|var merge|var sortBy)\b[\s\S]+?\n\1}/g);
|
||||||
|
|
||||||
if (!snippets) {
|
if (!snippets) {
|
||||||
|
|||||||
17
lodash.js
17
lodash.js
@@ -678,15 +678,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by `sortBy` to compare transformed values of `collection`, sorting
|
* Used by `sortBy` to compare transformed `collection` values, sorting them
|
||||||
* them in ascending order.
|
* stabily in ascending order.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @param {Object} a The object to compare to `b`.
|
* @param {Object} a The object to compare to `b`.
|
||||||
* @param {Object} b The object to compare to `a`.
|
* @param {Object} b The object to compare to `a`.
|
||||||
* @returns {Number} Returns `-1` if `a` < `b`, `0` if `a` == `b`, or `1` if `a` > `b`.
|
* @returns {Number} Returns the sort order indicator of `1` or `-1`.
|
||||||
*/
|
*/
|
||||||
function compareAscending(a, b) {
|
function compareAscending(a, b) {
|
||||||
|
var ai = a.index,
|
||||||
|
bi = b.index;
|
||||||
|
|
||||||
a = a.criteria;
|
a = a.criteria;
|
||||||
b = b.criteria;
|
b = b.criteria;
|
||||||
|
|
||||||
@@ -696,7 +699,9 @@
|
|||||||
if (b === undefined) {
|
if (b === undefined) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return a < b ? -1 : a > b ? 1 : 0;
|
// ensure a stable sort in V8 and other engines
|
||||||
|
// http://code.google.com/p/v8/issues/detail?id=90
|
||||||
|
return a < b ? -1 : a > b ? 1 : ai < bi ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -746,7 +751,7 @@
|
|||||||
function isPlainObject(value) {
|
function isPlainObject(value) {
|
||||||
// avoid non-objects and false positives for `arguments` objects in IE < 9
|
// avoid non-objects and false positives for `arguments` objects in IE < 9
|
||||||
var result = false;
|
var result = false;
|
||||||
if (!(value && typeof value == 'object') || (noArgumentsClass && isArguments(value))) {
|
if (!(value && typeof value == 'object') || (noArgsClass && isArguments(value))) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
// IE < 9 presents DOM nodes as `Object` objects except they have `toString`
|
// IE < 9 presents DOM nodes as `Object` objects except they have `toString`
|
||||||
@@ -2272,11 +2277,13 @@
|
|||||||
'array':
|
'array':
|
||||||
'result[index] = {\n' +
|
'result[index] = {\n' +
|
||||||
' criteria: callback(value, index, collection),\n' +
|
' criteria: callback(value, index, collection),\n' +
|
||||||
|
' index: index,\n' +
|
||||||
' value: value\n' +
|
' value: value\n' +
|
||||||
'}',
|
'}',
|
||||||
'object':
|
'object':
|
||||||
'result' + (isKeysFast ? '[ownIndex] = ' : '.push') + '({\n' +
|
'result' + (isKeysFast ? '[ownIndex] = ' : '.push') + '({\n' +
|
||||||
' criteria: callback(value, index, collection),\n' +
|
' criteria: callback(value, index, collection),\n' +
|
||||||
|
' index: index,\n' +
|
||||||
' value: value\n' +
|
' value: value\n' +
|
||||||
'})'
|
'})'
|
||||||
},
|
},
|
||||||
|
|||||||
22
test/test.js
22
test/test.js
@@ -1112,6 +1112,28 @@
|
|||||||
QUnit.module('lodash.sortBy');
|
QUnit.module('lodash.sortBy');
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
test('should perform a stable sort', function() {
|
||||||
|
function Pair(x, y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
var collection = [
|
||||||
|
new Pair(1, 1), new Pair(1, 2),
|
||||||
|
new Pair(1, 3), new Pair(1, 4),
|
||||||
|
new Pair(1, 5), new Pair(1, 6),
|
||||||
|
new Pair(2, 1), new Pair(2, 2),
|
||||||
|
new Pair(2, 3), new Pair(2, 4),
|
||||||
|
new Pair(2, 5), new Pair(2, 6)
|
||||||
|
];
|
||||||
|
|
||||||
|
var actual = _.sortBy(collection, function(pair) {
|
||||||
|
return pair.x;
|
||||||
|
});
|
||||||
|
|
||||||
|
deepEqual(actual, collection);
|
||||||
|
});
|
||||||
|
|
||||||
test('supports the `thisArg` argument', function() {
|
test('supports the `thisArg` argument', function() {
|
||||||
var actual = _.sortBy([1, 2, 3], function(num) {
|
var actual = _.sortBy([1, 2, 3], function(num) {
|
||||||
return this.sin(num);
|
return this.sin(num);
|
||||||
|
|||||||
Reference in New Issue
Block a user