Add _.nth.

This commit is contained in:
John-David Dalton
2016-04-11 20:33:59 -07:00
parent bfe6e06b5a
commit 2469af6c3f
3 changed files with 136 additions and 27 deletions

View File

@@ -69,16 +69,17 @@ exports.aryMethod = {
'get', 'groupBy', 'gt', 'gte', 'has', 'hasIn', 'includes', 'indexOf', 'get', 'groupBy', 'gt', 'gte', 'has', 'hasIn', 'includes', 'indexOf',
'intersection', 'invertBy', 'invoke', 'invokeMap', 'isEqual', 'isMatch', 'intersection', 'invertBy', 'invoke', 'invokeMap', 'isEqual', 'isMatch',
'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map', 'mapKeys', 'mapValues', 'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map', 'mapKeys', 'mapValues',
'matchesProperty', 'maxBy', 'meanBy', 'merge', 'minBy', 'multiply', 'omit', 'omitBy', 'matchesProperty', 'maxBy', 'meanBy', 'merge', 'minBy', 'multiply', 'nth',
'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt', 'partial', 'partialRight', 'omit', 'omitBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt',
'partition', 'pick', 'pickBy', 'pull', 'pullAll', 'pullAt', 'random', 'range', 'partial', 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll',
'rangeRight', 'rearg', 'reject', 'remove', 'repeat', 'restFrom', 'result', 'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove',
'sampleSize', 'some', 'sortBy', 'sortedIndex', 'sortedIndexOf', 'sortedLastIndex', 'repeat', 'restFrom', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex',
'sortedLastIndexOf', 'sortedUniqBy', 'split', 'spreadFrom', 'startsWith', 'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy',
'subtract', 'sumBy', 'take', 'takeRight', 'takeRightWhile', 'takeWhile', 'tap', 'split', 'spreadFrom', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight',
'throttle', 'thru', 'times', 'trimChars', 'trimCharsEnd', 'trimCharsStart', 'takeRightWhile', 'takeWhile', 'tap', 'throttle', 'thru', 'times', 'trimChars',
'truncate', 'union', 'uniqBy', 'uniqWith', 'unset', 'unzipWith', 'without', 'trimCharsEnd', 'trimCharsStart', 'truncate', 'union', 'uniqBy', 'uniqWith',
'wrap', 'xor', 'zip', 'zipObject', 'zipObjectDeep' 'unset', 'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject',
'zipObjectDeep'
], ],
'3': [ '3': [
'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith', 'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith',

View File

@@ -1552,7 +1552,7 @@
* `isSet`, `isString`, `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`, * `isSet`, `isString`, `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`,
* `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`, * `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`,
* `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, `min`, `minBy`, `multiply`, * `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, `min`, `minBy`, `multiply`,
* `noConflict`, `noop`, `now`, `pad`, `padEnd`, `padStart`, `parseInt`, * `noConflict`, `noop`, `now`, `nth`, `pad`, `padEnd`, `padStart`, `parseInt`,
* `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `round`, * `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `round`,
* `runInContext`, `sample`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, * `runInContext`, `sample`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`,
* `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`, `startCase`, * `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`, `startCase`,
@@ -3293,6 +3293,23 @@
assignMergeValue(object, key, newValue); assignMergeValue(object, key, newValue);
} }
/**
* The base implementation of `_.nth` which doesn't coerce `n` to an integer.
*
* @private
* @param {Array} array The array to inspect.
* @param {number} n The index of the element to return.
* @returns {*} Returns the nth element.
*/
function baseNth(array, n) {
var length = array.length;
if (!length) {
return undefined;
}
n += n < 0 ? length : 0;
return isIndex(n, length) ? array[n] : undefined;
}
/** /**
* The base implementation of `_.orderBy` without param guards. * The base implementation of `_.orderBy` without param guards.
* *
@@ -6654,6 +6671,31 @@
return -1; return -1;
} }
/**
* Gets the nth element of `array`. If `n` is negative, the nth element
* from the end is returned.
*
* @static
* @memberOf _
* @since 4.11.0
* @category Array
* @param {Array} array The array to inspect.
* @param {number} [n=0] The index of the element to return..
* @returns {*} Returns the nth element.
* @example
*
* var array = ['a', 'b', 'c', 'd'];
*
* _.nth(array, 1);
* // => 'b'
*
* _.nth(array, -2);
* // => 'c';
*/
function nth(array, n) {
return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
}
/** /**
* Removes all given values from `array` using * Removes all given values from `array` using
* [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
@@ -14715,7 +14757,8 @@
} }
/** /**
* Creates a function that returns its nth argument. * Creates a function that returns its nth argument. If `n` is negative,
* the nth argument from the end is returned.
* *
* @static * @static
* @memberOf _ * @memberOf _
@@ -14726,15 +14769,18 @@
* @example * @example
* *
* var func = _.nthArg(1); * var func = _.nthArg(1);
* * func('a', 'b', 'c', 'd');
* func('a', 'b', 'c');
* // => 'b' * // => 'b'
*
* var func = _.nthArg(-2);
* func('a', 'b', 'c', 'd');
* // => 'c'
*/ */
function nthArg(n) { function nthArg(n) {
n = toInteger(n); n = toInteger(n);
return function() { return rest(function(args) {
return arguments[n]; return baseNth(args, n);
}; });
} }
/** /**
@@ -15642,6 +15688,7 @@
lodash.min = min; lodash.min = min;
lodash.minBy = minBy; lodash.minBy = minBy;
lodash.multiply = multiply; lodash.multiply = multiply;
lodash.nth = nth;
lodash.noConflict = noConflict; lodash.noConflict = noConflict;
lodash.noop = noop; lodash.noop = noop;
lodash.now = now; lodash.now = now;

View File

@@ -15786,20 +15786,81 @@
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
QUnit.module('lodash.nthArg'); QUnit.module('lodash.nth');
(function() { (function() {
QUnit.test('should create a function that returns its nth argument', function(assert) { var array = ['a', 'b', 'c', 'd'];
QUnit.test('should get the nth element of `array`', function(assert) {
assert.expect(1); assert.expect(1);
var expected = ['a', 'b', 'c']; var actual = lodashStable.map(array, function(value, index) {
return _.nth(array, index);
});
var actual = lodashStable.times(expected.length, function(n) { assert.deepEqual(actual, array);
var func = _.nthArg(n); });
return func.apply(undefined, expected);
QUnit.test('should work with a negative `n`', function(assert) {
assert.expect(1);
var actual = lodashStable.map(lodashStable.range(1, array.length + 1), function(n) {
return _.nth(array, -n);
});
assert.deepEqual(actual, ['d', 'c', 'b', 'a']);
});
QUnit.test('should coerce `n` to an integer', function(assert) {
assert.expect(2);
var values = falsey,
expected = lodashStable.map(values, alwaysA);
var actual = lodashStable.map(values, function(n) {
return n ? _.nth(array, n) : _.nth(array);
}); });
assert.deepEqual(actual, expected); assert.deepEqual(actual, expected);
values = ['1', 1.6];
expected = lodashStable.map(values, alwaysB);
actual = lodashStable.map(values, function(n) {
return _.nth(array, n);
});
assert.deepEqual(actual, expected);
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.nthArg');
(function() {
var args = ['a', 'b', 'c', 'd'];
QUnit.test('should create a function that returns its nth argument', function(assert) {
assert.expect(1);
var actual = lodashStable.map(args, function(value, index) {
var func = _.nthArg(index);
return func.apply(undefined, args);
});
assert.deepEqual(actual, args);
});
QUnit.test('should work with a negative `n`', function(assert) {
assert.expect(1);
var actual = lodashStable.map(lodashStable.range(1, args.length + 1), function(n) {
var func = _.nthArg(-n);
return func.apply(undefined, args);
});
assert.deepEqual(actual, ['d', 'c', 'b', 'a']);
}); });
QUnit.test('should coerce `n` to an integer', function(assert) { QUnit.test('should coerce `n` to an integer', function(assert) {
@@ -15810,7 +15871,7 @@
var actual = lodashStable.map(values, function(n) { var actual = lodashStable.map(values, function(n) {
var func = n ? _.nthArg(n) : _.nthArg(); var func = n ? _.nthArg(n) : _.nthArg();
return func('a', 'b', 'c'); return func.apply(undefined, args);
}); });
assert.deepEqual(actual, expected); assert.deepEqual(actual, expected);
@@ -15820,7 +15881,7 @@
actual = lodashStable.map(values, function(n) { actual = lodashStable.map(values, function(n) {
var func = _.nthArg(n); var func = _.nthArg(n);
return func('a', 'b', 'c'); return func.apply(undefined, args);
}); });
assert.deepEqual(actual, expected); assert.deepEqual(actual, expected);
@@ -17799,7 +17860,7 @@
assert.deepEqual(func(1, 5, 20), [1]); assert.deepEqual(func(1, 5, 20), [1]);
}); });
QUnit.test('`_.' + methodName + '` should work with a negative `step` argument', function(assert) { QUnit.test('`_.' + methodName + '` should work with a negative `step`', function(assert) {
assert.expect(2); assert.expect(2);
assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3])); assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3]));
@@ -25520,7 +25581,7 @@
var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey); var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey);
QUnit.test('should accept falsey arguments', function(assert) { QUnit.test('should accept falsey arguments', function(assert) {
assert.expect(307); assert.expect(308);
var emptyArrays = lodashStable.map(falsey, alwaysEmptyArray); var emptyArrays = lodashStable.map(falsey, alwaysEmptyArray);