Simplify baseValues, createCompounder, initKeys, _.after, _.pairs, _.range, & _.times.

This commit is contained in:
John-David Dalton
2015-08-29 09:12:49 -07:00
parent f016840c53
commit 4d2aa29926
2 changed files with 46 additions and 96 deletions

108
lodash.js
View File

@@ -2652,6 +2652,25 @@
return result; return result;
} }
/**
* The base implementation of `_.times` without support for callback shorthands
* or max array length checks.
*
* @private
* @param {number} n The number of times to invoke `iteratee`.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns the array of results.
*/
function baseTimes(n, iteratee) {
var index = -1,
result = Array(n);
while (++index < n) {
result[index] = iteratee(index);
}
return result;
}
/** /**
* The base implementation of `_.uniq`. * The base implementation of `_.uniq`.
* *
@@ -2726,14 +2745,9 @@
* @returns {Object} Returns the array of property values. * @returns {Object} Returns the array of property values.
*/ */
function baseValues(object, props) { function baseValues(object, props) {
var index = -1, return arrayMap(props, function(key) {
length = props.length, return object[key];
result = Array(length); });
while (++index < length) {
result[index] = object[props[index]];
}
return result;
} }
/** /**
@@ -3149,15 +3163,7 @@
*/ */
function createCompounder(callback) { function createCompounder(callback) {
return function(string) { return function(string) {
var index = -1, return arrayReduce(words(deburr(string)), callback, '');
array = words(deburr(string)),
length = array.length,
result = '';
while (++index < length) {
result = callback(result, array[index], index);
}
return result;
}; };
} }
@@ -3893,13 +3899,7 @@
length = (length && isLength(length) && length = (length && isLength(length) &&
(isArray(object) || isArguments(object) || isString(object)) && length) || 0; (isArray(object) || isArguments(object) || isString(object)) && length) || 0;
var index = -1, return baseTimes(length, String);
result = Array(length);
while (++index < length) {
result[index] = (index + '');
}
return result;
} }
/** /**
@@ -6732,15 +6732,9 @@
*/ */
function after(n, func) { function after(n, func) {
if (typeof func != 'function') { if (typeof func != 'function') {
if (typeof n == 'function') { throw new TypeError(FUNC_ERROR_TEXT);
var temp = n;
n = func;
func = temp;
} else {
throw new TypeError(FUNC_ERROR_TEXT);
}
} }
n = nativeIsFinite(n = +n) ? n : 0; n = toInteger(n);
return function() { return function() {
if (--n < 1) { if (--n < 1) {
return func.apply(this, arguments); return func.apply(this, arguments);
@@ -6791,6 +6785,7 @@
if (typeof func != 'function') { if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT); throw new TypeError(FUNC_ERROR_TEXT);
} }
n = toInteger(n);
return function() { return function() {
if (--n > 0) { if (--n > 0) {
result = func.apply(this, arguments); result = func.apply(this, arguments);
@@ -9453,17 +9448,9 @@
*/ */
function pairs(object) { function pairs(object) {
object = Object(object); object = Object(object);
return arrayMap(keys(object), function(key) {
var index = -1, return [key, object[key]];
props = keys(object), });
length = props.length,
result = Array(length);
while (++index < length) {
var key = props[index];
result[index] = [key, object[key]];
}
return result;
} }
/** /**
@@ -11099,17 +11086,10 @@
} else { } else {
end = +end || 0; end = +end || 0;
} }
// Use `Array(length)` so engines like Chakra and V8 avoid slower modes. var n = nativeMax(nativeCeil((end - start) / (step || 1)), 0);
// See https://youtu.be/XAqIpGU8ZZk#t=17m25s for more details. return baseTimes(n, function(index) {
var index = -1, return index ? (start += step) : start;
length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), });
result = Array(length);
while (++index < length) {
result[index] = start;
start += step;
}
return result;
} }
/** /**
@@ -11133,23 +11113,19 @@
* // => invokes `mage.castSpell` three times with `n` of `0`, `1`, and `2` * // => invokes `mage.castSpell` three times with `n` of `0`, `1`, and `2`
*/ */
function times(n, iteratee) { function times(n, iteratee) {
n = nativeFloor(n); n = toInteger(n);
if (n < 1 || n == POSITIVE_INFINITY || n == NEGATIVE_INFINITY) {
// Exit early to avoid a JSC JIT bug in Safari 8
// where `Array(0)` is treated as `Array(1)`.
if (n < 1 || !nativeIsFinite(n)) {
return []; return [];
} }
var index = -1, var index = MAX_ARRAY_LENGTH,
result = Array(nativeMin(n, MAX_ARRAY_LENGTH)); length = nativeMin(n, MAX_ARRAY_LENGTH);
iteratee = toFunction(iteratee); iteratee = toFunction(iteratee);
n -= MAX_ARRAY_LENGTH;
var result = baseTimes(length, iteratee);
while (++index < n) { while (++index < n) {
if (index < MAX_ARRAY_LENGTH) { iteratee(index);
result[index] = iteratee(index);
} else {
iteratee(index);
}
} }
return result; return result;
} }

View File

@@ -866,27 +866,8 @@
strictEqual(after(0, 1), 1, 'after(0) should invoke `func` when called once'); strictEqual(after(0, 1), 1, 'after(0) should invoke `func` when called once');
}); });
test('should coerce non-finite `n` values to `0`', 1, function() { test('should coerce `n` values of `NaN` to `0`', 1, function() {
var values = [-Infinity, NaN, Infinity], strictEqual(after(NaN, 1), 1);
expected = _.map(values, _.constant(1));
var actual = _.map(values, function(n) {
return after(n, 1);
});
deepEqual(actual, expected);
});
test('should allow `func` as the first argument', 1, function() {
var count = 0;
try {
var after = _.after(function() { count++; }, 1);
after();
after();
} catch(e) {}
strictEqual(count, 2);
}); });
test('should not set a `this` binding', 2, function() { test('should not set a `this` binding', 2, function() {
@@ -1179,15 +1160,8 @@
strictEqual(before(0, 1), 0, 'before(0) should not invoke `func` when called'); strictEqual(before(0, 1), 0, 'before(0) should not invoke `func` when called');
}); });
test('should coerce non-finite `n` values to `0`', 1, function() { test('should coerce `n` values of `NaN` to `0`', 1, function() {
var values = [-Infinity, NaN, Infinity], strictEqual(before(NaN, 1), 0);
expected = _.map(values, _.constant(0));
var actual = _.map(values, function(n) {
return before(n);
});
deepEqual(actual, expected);
}); });
test('should not set a `this` binding', 2, function() { test('should not set a `this` binding', 2, function() {