From 2ae0e9d902fd6ba357696267d069e54f750aa817 Mon Sep 17 00:00:00 2001 From: Dan Heberden Date: Tue, 18 Dec 2012 10:00:24 -0800 Subject: [PATCH 1/4] add `grab` method to get elements in a collection that match the indexes in the provided list array Former-commit-id: 18df81c229cab4acde8f8157df9bb1001a51e9db --- lodash.js | 20 ++++++++++++++++++++ test/test.js | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/lodash.js b/lodash.js index 7e659648c..f3d8b4634 100644 --- a/lodash.js +++ b/lodash.js @@ -2175,6 +2175,25 @@ return collection; } + /** + * Grabs the elements in the `collection` using the specified indexes + * in the `list` array. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Array} list The array of indexes to grab. + * @ returns {Array} Returns a new array of elements that matched the list array. + * @example + * + * _.grab( ['a', 'b', 'c', 'd', 'e', 'f'], [0, 2, 5] ); + * // => ['a', 'c', 'f'] + */ + function grab(collection, list) { + return invoke(list, function(a){ return a[this]; }, collection); + } + /** * Creates an object composed of keys returned from running each element of * `collection` through a `callback`. The corresponding value of each key is an @@ -4239,6 +4258,7 @@ lodash.forIn = forIn; lodash.forOwn = forOwn; lodash.functions = functions; + lodash.grab = grab; lodash.groupBy = groupBy; lodash.initial = initial; lodash.intersection = intersection; diff --git a/test/test.js b/test/test.js index c1b12c470..7b767d449 100644 --- a/test/test.js +++ b/test/test.js @@ -667,6 +667,28 @@ /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.grab'); + + (function() { + test('should get items in range', function() { + var result = _.grab(['a', 'b', 1.4, 'c', { 'foo': 'bar' }, 'd'], [0, 2, 4]); + deepEqual( result, ['a', 1.4, { 'foo': 'bar' } ]); + }); + test('should work with an object for `collection`', function() { + var result = _.grab({ 'a': 'apple', 'b': 'ball', 'c': 'count' }, ['a', 'c']); + deepEqual(result, ['apple', 'count']); + }); + test('no list should return an empty array', function() { + deepEqual(_.grab(['a', 'b', 'c']), [] ); + }); + test('out of range selections should return undefined', function() { + var result = _.grab(['a', 'b', 'c'], [1, 9001]); + deepEqual( result, ['b', undefined]); + }); + }()); + + /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.groupBy'); (function() { From c86a16df7fc69e58e5ac01b13743c0ffc5da0ec5 Mon Sep 17 00:00:00 2001 From: Dan Heberden Date: Tue, 18 Dec 2012 12:52:44 -0800 Subject: [PATCH 2/4] change .grab to .at, add unlimited args or numbers or arrays and simplify function call to use values and pick Former-commit-id: 3deb82ad9f55cd7261453a40bb0f046a5340790d --- lodash.js | 44 ++++++++++++++++++++++++-------------------- test/test.js | 12 ++++-------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/lodash.js b/lodash.js index f3d8b4634..26d737388 100644 --- a/lodash.js +++ b/lodash.js @@ -1937,6 +1937,29 @@ /*--------------------------------------------------------------------------*/ + /** + * Retrieves the elements in the `collection` at specified indexes. Indexes may + * be specified as individual arguments or as arrays of indexes. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Number|Array} number|[index1, index2, ...] The index(es) of `collection` + * to retrieve, either as individual arguments or arrays. + * @returns {Array} Returns a new array of elements that matched the provided indexes. + * @example + * + * _.at( ['a', 'b', 'c', 'd', 'e', 'f'], [0, 2, 5] ); + * // => ['a', 'c', 'f'] + * + * _.at( ['lodash', 'javascript', 'fast'], 0, 2 ); + * // => ['lodash, 'fast'] + */ + function at(collection, list) { + return values(pick(collection || [], concat.apply(arguments, slice(arguments, 1)))); + } + /** * Checks if a given `target` element is present in a `collection` using strict * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used @@ -2175,25 +2198,6 @@ return collection; } - /** - * Grabs the elements in the `collection` using the specified indexes - * in the `list` array. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Array} list The array of indexes to grab. - * @ returns {Array} Returns a new array of elements that matched the list array. - * @example - * - * _.grab( ['a', 'b', 'c', 'd', 'e', 'f'], [0, 2, 5] ); - * // => ['a', 'c', 'f'] - */ - function grab(collection, list) { - return invoke(list, function(a){ return a[this]; }, collection); - } - /** * Creates an object composed of keys returned from running each element of * `collection` through a `callback`. The corresponding value of each key is an @@ -4241,6 +4245,7 @@ // add functions that return wrapped values when chaining lodash.after = after; lodash.assign = assign; + lodash.at = at; lodash.bind = bind; lodash.bindAll = bindAll; lodash.bindKey = bindKey; @@ -4258,7 +4263,6 @@ lodash.forIn = forIn; lodash.forOwn = forOwn; lodash.functions = functions; - lodash.grab = grab; lodash.groupBy = groupBy; lodash.initial = initial; lodash.intersection = intersection; diff --git a/test/test.js b/test/test.js index 7b767d449..4bb64da7d 100644 --- a/test/test.js +++ b/test/test.js @@ -667,23 +667,19 @@ /*--------------------------------------------------------------------------*/ - QUnit.module('lodash.grab'); + QUnit.module('lodash.at'); (function() { test('should get items in range', function() { - var result = _.grab(['a', 'b', 1.4, 'c', { 'foo': 'bar' }, 'd'], [0, 2, 4]); + var result = _.at(['a', 'b', 1.4, 'c', { 'foo': 'bar' }, 'd'], [0, 2, 4]); deepEqual( result, ['a', 1.4, { 'foo': 'bar' } ]); }); test('should work with an object for `collection`', function() { - var result = _.grab({ 'a': 'apple', 'b': 'ball', 'c': 'count' }, ['a', 'c']); + var result = _.at({ 'a': 'apple', 'b': 'ball', 'c': 'count' }, ['a', 'c']); deepEqual(result, ['apple', 'count']); }); test('no list should return an empty array', function() { - deepEqual(_.grab(['a', 'b', 'c']), [] ); - }); - test('out of range selections should return undefined', function() { - var result = _.grab(['a', 'b', 'c'], [1, 9001]); - deepEqual( result, ['b', undefined]); + deepEqual(_.at(['a', 'b', 'c']), [] ); }); }()); From 4a0897c73438534668cccb799e6a3c1da51cc06e Mon Sep 17 00:00:00 2001 From: Dan Heberden Date: Tue, 18 Dec 2012 15:09:57 -0800 Subject: [PATCH 3/4] build in functionality to at, add string support, optimize, and add more tests Former-commit-id: 951ef27e55fff5a70d09916b55b85f9e725f751a --- lodash.js | 16 ++++++++++++++-- test/test.js | 6 ++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lodash.js b/lodash.js index 26d737388..6449dad27 100644 --- a/lodash.js +++ b/lodash.js @@ -1956,8 +1956,20 @@ * _.at( ['lodash', 'javascript', 'fast'], 0, 2 ); * // => ['lodash, 'fast'] */ - function at(collection, list) { - return values(pick(collection || [], concat.apply(arguments, slice(arguments, 1)))); + function at(collection) { + var index = -1, + props = concat.apply(arrayRef, slice(arguments, 1)), + length = props.length, + result = Array(length); + + if (noCharByIndex && isString(collection)) { + collection = collection.split(''); + } + + while(++index < length) { + result[index] = collection[props[index]]; + } + return result; } /** diff --git a/test/test.js b/test/test.js index 4bb64da7d..95375298d 100644 --- a/test/test.js +++ b/test/test.js @@ -681,6 +681,12 @@ test('no list should return an empty array', function() { deepEqual(_.at(['a', 'b', 'c']), [] ); }); + test('should work on strings', function() { + deepEqual(_.at("helio", [0,3]), ['h', 'i']); + }); + test('should work with multple args', function() { + deepEqual(_.at(['a','b','c','d'], 0, 2, 3), ['a', 'c', 'd']); + }); }()); /*--------------------------------------------------------------------------*/ From eccd6463f65607ed49f28af25162dccc08a6004b Mon Sep 17 00:00:00 2001 From: Dan Heberden Date: Tue, 18 Dec 2012 15:30:38 -0800 Subject: [PATCH 4/4] update dependency for at method Former-commit-id: 600a1079d3591880654df0b861810b7c070047e9 --- build.js | 1 + 1 file changed, 1 insertion(+) diff --git a/build.js b/build.js index 0f42a66cf..3f699546a 100755 --- a/build.js +++ b/build.js @@ -67,6 +67,7 @@ var dependencyMap = { 'after': [], 'assign': ['isArguments'], + 'at': ['isString'], 'bind': ['isFunction', 'isObject'], 'bindAll': ['bind', 'functions'], 'bindKey': ['isFunction', 'isObject'],