underscore.js So what exactly does Underscore do? "Underscore is a utility-belt library for JavaScript that provides a lot of the functional programming support that you would expect in Prototype.js (or Ruby), but without extending any of the built-in JavaScript objects. One of the nicer things about working in Python or Ruby are the fancy constructs like map that make life a lot easier. The current version of JavaScript, sadly, is fairly barebones when it comes to low level utilities." Collection Function contains _.contains(list, value, [fromIndex]) Alias: includes Determine if the array or object contains a given item (using ===). Aliased as includes and include. _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { if (!isArrayLike(obj)) obj = _.values(obj); if (typeof fromIndex != 'number' || guard) fromIndex = 0; return _.indexOf(obj, item, fromIndex) >= 0; }; Returns true if the value is present in the list. Uses indexOf internally, if list is an Array. Use fromIndex to start your search at a given index. _.contains([1, 2, 3], 3); >> true each _.each(list, iteratee, [context]) Alias: forEach The cornerstone, an each implementation, aka forEach. Handles raw objects in addition to array-likes. Treats all sparse array-likes as if they were dense. _.each = _.forEach = function(obj, iteratee, context) { iteratee = optimizeCb(iteratee, context); var i, length; if (isArrayLike(obj)) { for (i = 0, length = obj.length; i < length; i++) { iteratee(obj[i], i, obj); } } else { var keys = _.keys(obj); for (i = 0, length = keys.length; i < length; i++) { iteratee(obj[keys[i]], keys[i], obj); } } return obj; }; Iterates over a list of elements, yielding each in turn to an iteratee function.The iteratee is bound to the context object, if one is passed. Each invocation of iteratee is called with three arguments: (element, index, list). If list is a JavaScript object, iteratee's arguments will be (value, key, list). Returns the list for chaining. _.each([1, 2, 3], alert); >> alerts each number in turn... _.each({one: 1, two: 2, three: 3}, alert); >> alerts each number value in turn... filter _.filter(list, predicate, [context]) Alias: select Return all the elements that pass a truth test. Aliased as select. _.filter = _.select = function(obj, predicate, context) { var results = []; predicate = cb(predicate, context); _.each(obj, function(value, index, list) { if (predicate(value, index, list)) results.push(value); }); return results; }; Looks through each value in the list, returning an array of all the values that pass a truth test (predicate). var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); >> [2, 4, 6] find _.find(list, predicate, [context]) Alias: detect Return the first value which passes a truth test. Aliased as detect. _.find = _.detect = function(obj, predicate, context) { var key; if (isArrayLike(obj)) { key = _.findIndex(obj, predicate, context); } else { key = _.findKey(obj, predicate, context); } if (key !== void 0 && key !== -1) return obj[key]; }; Looks through each value in the list, returning the first one that passes a truth test (predicate), or undefined if no value passes the test. The function returns as soon as it finds an acceptable element, and doesn't traverse the entire list. var even = _.find([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); >> 2 findWhere _.findWhere(list, properties) Convenience version of a common use case of find: getting the first object containing specific key:value pairs. _.findWhere = function(obj, attrs) { return _.find(obj, _.matcher(attrs)); }; Looks through the list and returns the first value that matches all of the key-value pairs listed in properties. If no match is found, or if list is empty, undefined will be returned. _.findWhere(publicServicePulitzers, {newsroom: "The New York Times"}); => {year: 1918, newsroom: "The New York Times", reason: "For its public service in publishing in full so many official reports, documents and speeches by European statesmen relating to the progress and conduct of the war."} groupBy _.groupBy(list, iteratee, [context]) Groups the object’s values by a criterion. Pass either a string attribute to group by, or a function that returns the criterion. _.groupBy = group(function(result, value, key) { if (_.has(result, key)) result[key].push(value); else result[key] = [value]; }); Splits a collection into sets, grouped by the result of running each value through iteratee. If iteratee is a string instead of a function, groups by the property named by iteratee on each of the values. _.groupBy([1.3, 2.1, 2.4], function(num){ return Math.floor(num); }); >> {1: [1.3], 2: [2.1, 2.4]} _.groupBy(['one', 'two', 'three'], 'length'); >> {3: ["one", "two"], 5: ["three"]} invoke _.invoke(list, methodName, *arguments) Invoke a method (with arguments) on every item in a collection. _.invoke = function(obj, method) { var args = slice.call(arguments, 2); var isFunc = _.isFunction(method); return _.map(obj, function(value) { var func = isFunc ? method : value[method]; return func == null ? func : func.apply(value, args); }); }; Calls the method named by methodName on each value in the list. Any extra arguments passed to invoke will be forwarded on to the method invocation. _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); >> [[1, 5, 7], [1, 2, 3]] indexBy _.indexBy(list, iteratee, [context]) Indexes the object’s values by a criterion, similar to groupBy, but for when you know that your index values will be unique. _.indexBy = group(function(result, value, key) { result[key] = value; }); Given a list, and an iteratee function that returns a key for each element in the list (or a property name), returns an object with an index of each item. Just like groupBy, but for when you know your keys are unique. var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}]; _.indexBy(stooges, 'age'); >> { "40": {name: 'moe', age: 40}, "50": {name: 'larry', age: 50}, "60": {name: 'curly', age: 60} } map _.map(list, iteratee, [context]) Alias: collect Return the results of applying the iteratee to each element. _.map = _.collect = function(obj, iteratee, context) { iteratee = cb(iteratee, context); var keys = !isArrayLike(obj) && _.keys(obj), length = (keys || obj).length, results = Array(length); for (var index = 0; index < length; index++) { var currentKey = keys ? keys[index] : index; results[index] = iteratee(obj[currentKey], currentKey, obj); } return results; }; Produces a new array of values by mapping each value in list through a transformation function (iteratee). The iteratee is passed three arguments: the value, then the index (or key) of the iteration, and finally a reference to the entire list. _.map([1, 2, 3], function(num){ return num * 3; }); >> [3, 6, 9] _.map({one: 1, two: 2, three: 3}, function(num, key){ return num * 3; }); >> [3, 6, 9] _.map([[1, 2], [3, 4]], _.first); >> [1, 3] max _.max(list, [iteratee], [context]) Return the maximum element (or element-based computation). _.max = function(obj, iteratee, context) { var result = -Infinity, lastComputed = -Infinity, value, computed; if (iteratee == null && obj != null) { obj = isArrayLike(obj) ? obj : _.values(obj); for (var i = 0, length = obj.length; i < length; i++) { value = obj[i]; if (value > result) { result = value; } } } else { iteratee = cb(iteratee, context); _.each(obj, function(value, index, list) { computed = iteratee(value, index, list); if (computed > lastComputed || computed === -Infinity && result === -Infinity) { result = value; lastComputed = computed; } }); } return result; }; Returns the maximum value in list. If an iteratee function is provided, it will be used on each value to generate the criterion by which the value is ranked. -Infinity is returned if list is empty, so an isEmpty guard may be required. Non-numerical values in list will be ignored. var frnds = [{name: 'Urvish', age: 25}, {name: 'Sanket', age: 27}, {name: 'Samir', age: 30}]; _.max(frnds, function(frnd){ return frnd.age; }); >> {name: 'Samir', age: 30}; min _.min(list, [iteratee], [context]) Return the minimum element (or element-based computation). _.min = function(obj, iteratee, context) { var result = Infinity, lastComputed = Infinity, value, computed; if (iteratee == null && obj != null) { obj = isArrayLike(obj) ? obj : _.values(obj); for (var i = 0, length = obj.length; i < length; i++) { value = obj[i]; if (value < result) { result = value; } } } else { iteratee = cb(iteratee, context); _.each(obj, function(value, index, list) { computed = iteratee(value, index, list); if (computed < lastComputed || computed === Infinity && result === Infinity) { result = value; lastComputed = computed; } }); } return result; }; Returns the minimum value in list. If an iteratee function is provided, it will be used on each value to generate the criterion by which the value is ranked. Infinity is returned if list is empty, so an isEmpty guard may be required. Non-numerical values in list will be ignored. var numbers = [27, 4, 212, 62, 999]; _.min(numbers); >> 4 pluck _.pluck(list, propertyName) Convenience version of a common use case of map: fetching a property. _.pluck = function(obj, key) { return _.map(obj, _.property(key)); }; A convenient version of what is perhaps the most common use-case for map: extracting a list of property values. var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}]; _.pluck(stooges, 'name'); >> ["moe", "larry", "curly"] sortBy _.sortBy(list, iteratee, [context]) Sort the object’s values by a criterion produced by an iteratee. _.sortBy = function(obj, iteratee, context) { iteratee = cb(iteratee, context); return _.pluck(_.map(obj, function(value, index, list) { return { value: value, index: index, criteria: iteratee(value, index, list) }; }).sort(function(left, right) { var a = left.criteria; var b = right.criteria; if (a !== b) { if (a > b || a === void 0) return 1; if (a < b || b === void 0) return -1; } return left.index - right.index; }), 'value'); }; Returns a (stably) sorted copy of list, ranked in ascending order by the results of running each value through iteratee. iteratee may also be the string name of the property to sort by (eg. length). _.sortBy([1, 2, 3, 4, 5, 6], function(num){ return Math.sin(num); }); >> [5, 4, 6, 3, 1, 2] var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}]; _.sortBy(stooges, 'name'); >> [{name: 'curly', age: 60}, {name: 'larry', age: 50}, {name: 'moe', age: 40}]; size _.size(list) Return the number of elements in an object. _.size = function(obj) { if (obj == null) return 0; return isArrayLike(obj) ? obj.length : _.keys(obj).length; }; Return the number of values in the list. _.size({one: 1, two: 2, three: 3, four: 4}); >> 4 toArray _.toArray(list) Safely create a real, live array from anything iterable. _.toArray = function(obj) { if (!obj) return []; if (_.isArray(obj)) return slice.call(obj); if (isArrayLike(obj)) return _.map(obj, _.identity); return _.values(obj); }; Creates a real Array from the list (anything that can be iterated over). Useful for transmuting the arguments object. (function(){ return _.toArray(arguments).slice(1); })(1, 2, 3, 4); >> [2, 3, 4] where _.where(list, properties) Convenience version of a common use case of filter: selecting only objects containing specific key:value pairs. _.where = function(obj, attrs) { return _.filter(obj, _.matcher(attrs)); }; Looks through each value in the list, returning an array of all the values that contain all of the key-value pairs listed in properties. _.where(listOfPlays, {author: "Chetan Bhagat", year: 1611}); >> [{title: "half girlfriend", author: "Chetan Bhagat", year: 1611}, {title: "half girlfriend", author: "Chetan Bhagat", year: 1611}]