mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-08 18:17:48 +00:00
Optimize _.sortBy and remove the _.map dependency from _.sortBy.
Former-commit-id: f6a133f0d27e7a00cb54e2e8478066dcfbe05659
This commit is contained in:
2
build.js
2
build.js
@@ -168,7 +168,7 @@
|
|||||||
'shuffle': [],
|
'shuffle': [],
|
||||||
'size': ['keys'],
|
'size': ['keys'],
|
||||||
'some': ['identity'],
|
'some': ['identity'],
|
||||||
'sortBy': ['map'],
|
'sortBy': [],
|
||||||
'sortedIndex': ['bind'],
|
'sortedIndex': ['bind'],
|
||||||
'tap': [],
|
'tap': [],
|
||||||
'template': ['escape'],
|
'template': ['escape'],
|
||||||
|
|||||||
@@ -226,20 +226,24 @@
|
|||||||
// remove debug sourceURL use in `_.template`
|
// remove debug sourceURL use in `_.template`
|
||||||
source = source.replace(/(?:\s*\/\/.*\n)* *if *\(useSourceURL[^}]+}/, '');
|
source = source.replace(/(?:\s*\/\/.*\n)* *if *\(useSourceURL[^}]+}/, '');
|
||||||
|
|
||||||
// minify `_.sortBy` internal properties
|
// minify internal properties used by `_.sortBy`
|
||||||
(function() {
|
(function() {
|
||||||
var properties = ['criteria', 'value'],
|
var properties = ['criteria', 'value'],
|
||||||
snippet = (source.match(/( +)function sortBy\b[\s\S]+?\n\1}/) || 0)[0],
|
snippets = source.match(/( +)(?:function compareAscending|function sortBy|var toSortable)\b[\s\S]+?\n\1}/g);
|
||||||
result = snippet;
|
|
||||||
|
if (!snippets) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
snippets.forEach(function(snippet) {
|
||||||
|
var result = snippet;
|
||||||
|
|
||||||
if (snippet) {
|
|
||||||
// minify properties
|
// minify properties
|
||||||
properties.forEach(function(property, index) {
|
properties.forEach(function(property, index) {
|
||||||
result = result.replace(RegExp('\\b' + property + '\\b', 'g'), minNames[index]);
|
result = result.replace(RegExp('\\b' + property + '\\b', 'g'), minNames[index]);
|
||||||
});
|
});
|
||||||
// replace with modified snippet
|
// replace with modified snippet
|
||||||
source = source.replace(snippet, result);
|
source = source.replace(snippet, result);
|
||||||
}
|
});
|
||||||
}());
|
}());
|
||||||
|
|
||||||
// minify all compilable snippets
|
// minify all compilable snippets
|
||||||
|
|||||||
91
lodash.js
91
lodash.js
@@ -461,6 +461,28 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by `sortBy()` to compare values of the array returned by `toSortable()`,
|
||||||
|
* sorting them in ascending order.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} a The object to compare to `b`.
|
||||||
|
* @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`.
|
||||||
|
*/
|
||||||
|
function compareAscending(a, b) {
|
||||||
|
a = a.criteria;
|
||||||
|
b = b.criteria;
|
||||||
|
|
||||||
|
if (a === undefined) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (b === undefined) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return a < b ? -1 : a > b ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by `template()` to replace tokens with their corresponding code snippets.
|
* Used by `template()` to replace tokens with their corresponding code snippets.
|
||||||
*
|
*
|
||||||
@@ -534,7 +556,7 @@
|
|||||||
'init': '[]',
|
'init': '[]',
|
||||||
'inLoop': 'result.push(index)'
|
'inLoop': 'result.push(index)'
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by `template()` to replace "escape" template delimiters with tokens.
|
* Used by `template()` to replace "escape" template delimiters with tokens.
|
||||||
*
|
*
|
||||||
@@ -577,6 +599,35 @@
|
|||||||
return token + index;
|
return token + index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts `collection` to an array of objects by running each element through
|
||||||
|
* a transformation `callback`. Each object has a `criteria` property containing
|
||||||
|
* the transformed value to be sorted and a `value` property containing the
|
||||||
|
* original unmodified value. The `callback` is invoked with 3 arguments;
|
||||||
|
* for arrays they are (value, index, array) and for objects they are
|
||||||
|
* (value, key, object).
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Array|Object} collection The collection to convert.
|
||||||
|
* @param {Function} callback The function called per iteration.
|
||||||
|
* @returns {Array} Returns a new array of objects to sort.
|
||||||
|
*/
|
||||||
|
var toSortable = createIterator(mapIteratorOptions, {
|
||||||
|
'args': 'collection, callback',
|
||||||
|
'inLoop': {
|
||||||
|
'array':
|
||||||
|
'result[index] = {\n' +
|
||||||
|
' criteria: callback(collection[index], index, collection),\n' +
|
||||||
|
' value: collection[index]\n' +
|
||||||
|
'}',
|
||||||
|
'object':
|
||||||
|
'result.push({\n' +
|
||||||
|
' criteria: callback(collection[index], index, collection),\n' +
|
||||||
|
' value: collection[index]\n' +
|
||||||
|
'})'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -694,9 +745,10 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Splits `collection` into sets, grouped by the result of running each value
|
* Splits `collection` into sets, grouped by the result of running each value
|
||||||
* through `callback`. The `callback` is bound to `thisArg` and invoked with 3
|
* through `callback`. The `callback` is bound to `thisArg` and invoked with
|
||||||
* arguments; (value, index, array). The `callback` argument may also be the
|
* 3 arguments; for arrays they are (value, index, array) and for objects they
|
||||||
* name of a property to group by.
|
* are (value, key, object). The `callback` argument may also be the name of a
|
||||||
|
* property to group by.
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
@@ -956,9 +1008,11 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Produces a new sorted array, ranked in ascending order by the results of
|
* Produces a new sorted array, ranked in ascending order by the results of
|
||||||
* running each element of `collection` through `callback`. The `callback` is
|
* running each element of `collection` through a transformation `callback`.
|
||||||
* bound to `thisArg` and invoked with 3 arguments; (value, index, array). The
|
* The `callback` is bound to `thisArg` and invoked with 3 arguments;
|
||||||
* `callback` argument may also be the name of a property to sort by (e.g. 'length').
|
* for arrays they are (value, index, array) and for objects they are
|
||||||
|
* (value, key, object). The `callback` argument may also be the name of a
|
||||||
|
* property to sort by (e.g. 'length').
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
@@ -986,28 +1040,9 @@
|
|||||||
} else if (thisArg) {
|
} else if (thisArg) {
|
||||||
callback = iteratorBind(callback, thisArg);
|
callback = iteratorBind(callback, thisArg);
|
||||||
}
|
}
|
||||||
|
var result = toSortable(collection, callback).sort(compareAscending),
|
||||||
var result = map(collection, function(value, index) {
|
length = result.length;
|
||||||
return {
|
|
||||||
'criteria': callback(value, index, collection),
|
|
||||||
'value': value
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
result.sort(function(left, right) {
|
|
||||||
var a = left.criteria,
|
|
||||||
b = right.criteria;
|
|
||||||
|
|
||||||
if (a === undefined) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (b === undefined) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return a < b ? -1 : a > b ? 1 : 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
var length = result.length;
|
|
||||||
while (length--) {
|
while (length--) {
|
||||||
result[length] = result[length].value;
|
result[length] = result[length].value;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user