Add _.indexBy method and add a noop fallback for setBindData.

Former-commit-id: f8035b9a221ba7b625c21cb566c62931877da6ef
This commit is contained in:
John-David Dalton
2013-07-26 09:12:04 -07:00
parent e5b8e04dde
commit cf26447f7c
10 changed files with 498 additions and 292 deletions

View File

@@ -212,12 +212,12 @@
* `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
* `compose`, `concat`, `countBy`, `createCallback`, `debounce`, `defaults`,
* `defer`, `delay`, `difference`, `filter`, `flatten`, `forEach`, `forIn`,
* `forOwn`, `functions`, `groupBy`, `initial`, `intersection`, `invert`,
* `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
* `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`, `range`,
* `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`,
* `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, `unshift`,
* `unzip`, `values`, `where`, `without`, `wrap`, and `zip`
* `forOwn`, `functions`, `groupBy`, `indexBy`, `initial`, `intersection`,
* `invert`, `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`,
* `omit`, `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`,
* `range`, `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`,
* `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`,
* `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, and `zip`
*
* The non-chainable wrapper functions are:
* `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`,
@@ -531,6 +531,28 @@
return result;
}
/**
* Creates a function that aggregates a collection, creating an object composed
* of keys generated from the results of running each element of the collection
* through a callback. The given `setter` function sets the keys and values
* of the composed object.
*
* @private
* @param {Function} setter The setter function.
* @returns {Function} Returns the new aggregator function.
*/
function createAggregator(setter) {
return function(collection, callback, thisArg) {
var result = {};
callback = createCallback(callback, thisArg, 3);
forEach(collection, function(value, key, collection) {
key = String(callback(value, key, collection));
setter(result, value, key, collection);
});
return result;
};
}
/**
* Creates a function that, when called, invokes `func` with the `this` binding
* of `thisArg` and prepends any `partialArgs` to the arguments passed to the
@@ -1251,7 +1273,7 @@
* Checks if `value` is `NaN`.
*
* Note: This is not the same as native `isNaN`, which will return `true` for
* `undefined` and other values. See http://es5.github.io/#x15.1.2.4.
* `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
*
* @static
* @memberOf _
@@ -1544,10 +1566,11 @@
}
/**
* Creates an object composed of keys returned from running each element of the
* `collection` through the given `callback`. The corresponding value of each key
* is the number of times the key was returned by the `callback`. The `callback`
* is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
* Creates an object composed of keys generated from the results of running
* each element of the `collection` through the given `callback`. The corresponding
* value of each key is the number of times the key was returned by the `callback`.
* The `callback` is bound to `thisArg` and invoked with three arguments;
* (value, index|key, collection).
*
* If a property name is passed for `callback`, the created "_.pluck" style
* callback will return the property value of the given element.
@@ -1576,16 +1599,9 @@
* _.countBy(['one', 'two', 'three'], 'length');
* // => { '3': 2, '5': 1 }
*/
function countBy(collection, callback, thisArg) {
var result = {};
callback = createCallback(callback, thisArg, 3);
forEach(collection, function(value, key, collection) {
key = String(callback(value, key, collection));
(hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
});
return result;
}
var countBy = createAggregator(function(result, value, key) {
(hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
});
/**
* Checks if the `callback` returns a truthy value for **all** elements of a
@@ -1847,10 +1863,11 @@
}
/**
* Creates an object composed of keys returned from running each element of the
* `collection` through the `callback`. The corresponding value of each key is
* an array of elements passed to `callback` that returned the key. The `callback`
* is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
* Creates an object composed of keys generated from the results of running
* each element of the `collection` through the `callback`. The corresponding
* value of each key is an array of the elements responsible for generating
* the key. The `callback` is bound to `thisArg` and invoked with three
* arguments; (value, index|key, collection).
*
* If a property name is passed for `callback`, the created "_.pluck" style
* callback will return the property value of the given element.
@@ -1880,16 +1897,9 @@
* _.groupBy(['one', 'two', 'three'], 'length');
* // => { '3': ['one', 'two'], '5': ['three'] }
*/
function groupBy(collection, callback, thisArg) {
var result = {};
callback = createCallback(callback, thisArg, 3);
forEach(collection, function(value, key, collection) {
key = String(callback(value, key, collection));
(hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
});
return result;
}
var groupBy = createAggregator(function(result, value, key) {
(hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
});
/**
* Invokes the method named by `methodName` on each element in the `collection`,
@@ -2961,7 +2971,8 @@
/**
* Creates an array of numbers (positive and/or negative) progressing from
* `start` up to but not including `end`.
* `start` up to but not including `end`. If `start` is less than `stop` a
* zero-length range is created unless a negative `step` is specified.
*
* @static
* @memberOf _
@@ -3495,6 +3506,7 @@
return result;
};
}
// exit early if there is no `thisArg`
if (typeof thisArg == 'undefined') {
return func;
}
@@ -3512,9 +3524,7 @@
return func.call(thisArg, accumulator, value, index, collection);
};
}
return function() {
return func.apply(thisArg, arguments);
};
return bind(func, thisArg);
}
/**