Underscore-contrib (0.3.0)

The brass buckles on Underscore's utility belt - a contributors' library for Underscore.

While Underscore provides a bevy of useful tools to support functional programming in JavaScript, it can't (and shouldn't) be everything to everyone. Underscore-contrib is intended as a home for functions that, for various reasons, don't belong in Underscore proper. In particular, it aims to be:

a home for functions that are limited in scope, but solve certain point problems, and

a proving ground for features that belong in Underscore proper, but need some advocacy and/or evolution (or devolution) to get them there.

First, you'll need Underscore version 1.6.0 or higher. Then you can grab the relevant underscore-contrib sub-libraries and simply add something like the following to your pages:

<script type="text/javascript" src="underscore.js"></script> <script type="text/javascript" src="underscore.object.builders.js"></script>

At the moment there are no cross-contrib dependencies (i.e. each sub-library can stand by itself), but that may change in the future.

Using contrib in Node is very simple. Just install it with npm:

npm install underscore-contrib --save

Then require it within your project like so:

var _ = require('underscore-contrib');

The _ variable will be a copy of Underscore with contrib's methods already mixed in.

_.contrib is open sourced under the MIT license.

The _.contrib library currently contains a number of related capabilities, aggregated into the following files.

underscore.array.builders - functions to build arrays

underscore.array.selectors - functions to take things from arrays

underscore.collections.walk - functions to walk and transform nested JavaScript objects

underscore.function.arity - functions to manipulate and fix function argument arity

underscore.function.combinators - functions to combine functions to make new functions

underscore.function.iterators - functions to lazily produce, manipulate and consume sequence iterators

underscore.function.predicates - functions that return true or false based on some criteria

or based on some criteria underscore.object.builders - functions to build JavaScript objects

underscore.object.selectors - functions to pick things from JavaScript objects

underscore.util.existential - functions that check for the existence or truthiness of JavaScript data types

underscore.util.operators - functions that wrap common (or missing) JavaScript operators

underscore.util.strings - functions to work with strings

underscore.util.trampolines - functions to facilitate calling functions recursively without blowing the stack

The links above are to the annotated source code. Full-blown _.contrib documentation is in the works. Contributors welcomed.

Functions to build arrays. View Annotated Source

Signature: _.cat(... arrays:Array ...)

The _.cat function provides a way to concatenate zero or more heterogeneous arrays into one.

_.cat(); // 0-args //=> [] _.cat([]); // 1-arg, empty array //=> [] _.cat([1,2,3]); // 1-arg //=> [1,2,3] _.cat([1,2,3],[4,5,6]); // 2-args //=> [1,2,3,4,5,6] _.cat([1,2,3],[4,5,6],[7]); // 3+ args //=> [1,2,3,4,5,6,7]

Not every argument to _.cat needs to be an array; other types are accepted.

Signature: _.cat(... elems:Any ...)

_.cat(1,[2],3,4); // mixed args //=> [1,2,3,4]

The _.cat function will also work with the arguments object as if it were an array.

Signature: _.cat(... elems:Arguments ...)

function f(){ return _.cat(arguments, 4,5,6); } f(1,2,3); //=> [1,2,3,4,5,6]

The _.chunk function, by default, accepts an array and a number and splits and returns a new array representing the original array split into some number of arrays of the given size:

_.chunk([0,1,2,3], 2); //=> , [[0,1],[2,3]]

If the original array cannot completely fulfill the chunk scheme then the array returned will drop the undersized final chunk:

_.chunk([0,1,2,3,4], 2); //=> , [[0,1],[2,3]]

You can pass an optional third argument to _.chunk to pad out the final array chunk should it fall short. If the value given as the third argument is not an array then it is repeated the needed number of times:

_.chunk([0,1,2,3,4], 3, '_'); //=> , [[0,1,2],[3,'_','_']]

If you given an array as the optional third argument then that array is used to pad in-place as needed:

_.chunk([0,1,2,3,4], 3, ['a', 'b']); //=> , [[0,1,2],[3,'a','b']]

The _.chunkAll function is similar to _.chunk except for the following. First, _.chunkAll will never drop short chunks from the end:

_.chunkAll([0,1,2,3,4], 3); //=> , [[0,1,2],[3]]

Also, _.chunkAll takes an optional third argument signifying that paritions should be built from skipped regions:

_.chunkAll(_.range(1), 2, 4); //=> [[0,1],[4,5],[8,9]]

Signature: _.cons(head:Any, tail:Array)

The _.cons function provides a way to "construct" a new array by taking some element and putting it at the front of another array.

_.cons(0, []); //=> [0] _.cons(1, [2]); //=> [1,2] _.cons([0], [1,2,3]); //=> [0,1,2,3]

The _.cons function also can be used to create pairs if the second argument is not an array.

Signature: _.cons(head:Any, tail:Any)

_.cons(1, 2); //=> [1,2] _.cons([1], 2); //=> [[1],2]

Finally, _.cons will operate with the arguments object.

Signature: _.cons(head:Any, tail:Arguments)

function f() { return _.cons(0, arguments) } f(1,2,3); //=> [0,1,2,3]

The _.cycle function takes an integer value used to build an array of that size containing the number of iterations through the given array, strung end-to-end as many times as needed. An example is probably more instructive:

_.cycle(5, [1,2,3]); //=> [1,2,3,1,2]

The _.interpose function takes an array and an element and returns a new array with the given element inserted betwixt every element in the original array:

_.interpose([1,2,3], 0); //=> [1,0,2,0,3]

If there are no betweens (i.e. empty and single-element arrays), then the original array is returned:

_.interpose([1], 0); //=> [1] _.interpose([], 0); //=> []

The _.iterateUntil function takes a function used as a result generator, a function used as a stop-check and a seed value and returns an array of each generated result. The operation of _.iterateUntil is such that the result generator is passed the seed to start and each subsequent result which will continue until a result fails the check function (i.e. returns falsey). An example is best:

var dec = function(n) { return n - 1; }; var isPos = function(n) { return n > 0; };

The dec result generator takes a number and decrements it by one. The isPos predicate takes a number and returns true if it's positive. Using these two functions you can build an array of every number from 6 to 0 , inclusive:

_.iterateUntil(dec, isPos, 6); //=> [5,4,3,2,1]

That is, the array only contains every number from 5 down to 1 because when the result of dec got to 0 the isPos check failed (i.e. went falsey) thus terminating the execution.

The _.keepIndexed function takes an array and a function and returns a new array filled with the non-null return results of the given function on the elements or keys in the given array:

_.keepIndexed([1,2,3], function(k) { return i === 1 || i === 2; }); //=> [false, true, true]

If you return either null or undefined then the result is dropped from the resulting array:

_.keepIndexed(['a','b','c'], function(k, v) { if (k === 1) return v; }); //=> ['b']

There are times when a mapping operation produces results contained in arrays, but the final result should be flattened one level. For these circumstances you can use _.mapcat to produce results:

var array = [1,2,null,4,undefined,6]; var errors = _.mapcat(array, function(e,i) { if (e == null) { return ["Element @" + i + " is bad"]; } else { return []; } });

Inspecting the contents of errors shows:

["Element @2 is bad", "Element @4 is bad"]

The _.mapcat function is equivalent to _.cat.apply(array, _.map(array,fun)) .

The _.reductions function is similar to Underscore's builtin _.reduce function except that it returns an array of every intermediate value in the folding operation:

_.reductions([1,2,3,4,5], function(agg, n) { return agg + n; }, 0); //=> [1,3,6,10,15]

The last element in the array returned from _.reductions is the answer that you would get if you had just chosen to use _.reduce .

Signature: _.repeat(t:Integer, value:Any)

The _.repeat function takes an integer value used to build an array of that size containing the value given:

_.repeat(5, 'a'); //=> ['a','a','a','a','a']

The _.splitAt function takes an array and a numeric index and returns a new array with two embedded arrays representing a split of the original array at the index provided:

_.splitAt([1,2,3,4,5], 2); //=> [[1,2],[3,4,5]] _.splitAt([1,2,3,4,5], 0); //=> [[],[1,2,3,4,5]]

The operation of _.splitAt is safe if the index provided is outside the range of legal indices:

_.splitAt([1,2,3,4,5], 20000); //=> [[1,2,3,4,5],[]] _.splitAt([1,2,3,4,5], -1000); //=> [[],[1,2,3,4,5]] _.splitAt([], 0); //=> [[],[]]

The _.takeSkipping function takes an array and a number and returns a new array containing every nth element in the original array:

_.takeSkipping(_.range(10), 2); //=> [0,2,4,6,8]

The _.takeSkipping function is safe against numbers larger or smaller than the array size:

_.takeSkipping(_.range(10), 100000); //=> [0] _.takeSkipping(_.range(10), -100); //=> []

The _.weave function works similarly to _.interpose (shown above) except that it accepts an array used as the interposition values. In other words, _.weave takes two arrays and returns a new array with the original elements woven together. An example would help:

_.weave(['a','b','c'], [1,2,3]); //=> ['a',1,'b',2,'c',3]

The array returned from _.weave will be as long as the longest array given with the woven entries stopping according to the shortest array:

_.weave(['a','b','c'], [1]); //=> ['a',1,'b','c']

The _.interleave function is an alias for _.weave .

Functions to take things from arrays. View Annotated Source

Signature: _.best(array:Array, fun:Function)

Returns the "best" value in an array based on the result of a given function.

_.best([1, 2, 3, 4, 5], function(x, y) { return x > y; }); //=> 5

Signature: _.dropWhile(array:Array, pred:Function)

Drops elements for which the given function returns a truthy value.

_.dropWhile([-2,-1,0,1,2], isNeg); //=> [0,1,2]

Signature: _.keep(array:Array, fun:Function)

Returns an array of existy results of a function over a source array.

_.keep([1, 2, 3, 4, 5], function(val) { if (val % 3 === 0) { return val; } }); // => [3]

Signature: _.nth(array:Array, index:Number[, guard:Any])

The _.nth function is a convenience for the equivalent array[n] . The optional guard value allows _.nth to work correctly as a callback for _.map .

_.nth(['a','b','c'], 2); //=> 'c'

If given an index out of bounds then _.nth will return undefined :

_.nth(['a','b','c'], 2000); //=> undefined

The _.nth function can also be used in conjunction with _.map and _.compact like so:

var b = [['a'],['b'],[]]; _.compact(_.map(b, function(e) { return _.nth(e,0) })); //=> ['a','b']

If wrapping a function around _.nth is too tedious or you'd like to partially apply the index then Underscore-contrib offers any of _.flip2 , _.fix or rcurry2 to solve this.

Signature: _.keep(array:Array, fun:Function)

Takes an array and partitions it into sub-arrays as the given predicate changes truth sense.

_.partitionBy([1,2,2,3,1,1,5], _.isEven); // => [[1],[2,2],[3,1,1,5]] _.partitionBy([1,2,2,3,1,1,5], _.identity); // => [[1],[2,2],[3],[1,1],[5]]

Signature: _.second(array:Array, index:Number[, guard:Any])

The _.second function is a convenience for the equivalent array[1] . The optional guard value allows _.second to work correctly as a callback for _.map .

_.second(['a','b']); //=> 'b' _.map([['a','b'], _.range(10,20)], _.second); //=> ['b',11]

You can also pass an optional number to the _.second function to take a number of elements from an array starting with the second element and ending at the given index:

_.second(_.range(10), 5) //=> [1, 2, 3, 4]

Signature: _.takeWhile(array:Array, pred:Function)

The _.takeWhile function takes an array and a function and returns a new array containing the first n elements in the original array for which the given function returns a truthy value:

var isNeg = function(n) { return n < 0; }; _.takeWhile([-2,-1,0,1,2], isNeg); //=> [-2,-1]

Signature: _.third(array:Array, index:Number[, guard:Any])

The _.third function is a convenience for the equivalent array[2] . The optional guard value allows _.third to work correctly as a callback for _.map .

_.third(['a','b','c']); //=> 'c' _.map([['a','b','c'], _.range(10,20)], _.third); //=> ['c',12]

You can also pass an optional number to the _.third function to take a number of elements from an array starting with the third element and ending at the given index:

_.third(_.range(10), 5) //=> [2, 3, 4]

Functions to recursively walk collections which are trees.

Documentation should use Journo formats and standards.

_.walk = walk; postorder: function(obj, visitor, context) preorder: function(obj, visitor, context) walk(obj, visitor, null, context) map: function(obj, strategy, visitor, context) pluck: function(obj, propertyName) pluckRec: function(obj, propertyName) _.walk.collect = _.walk.map;

Functions which manipulate the way functions work with their arguments.

Signature: _.arity(numberOfArgs:Number, fun:Function)

Returns a new function which is equivalent to fun , except that the new function's length property is equal to numberOfArgs . This does not limit the function to using that number of arguments. It's only effect is on the reported length.

function addAll() { var sum = 0; for (var i = 0; i < arguments.length; i++) { sum = sum + arguments[i]; } return sum; } addAll.length // => 0 var addAllWithFixedLength = _.arity(2, addAll); addAllWithFixedLength.length // => 2 addAllWithFixedLength(1, 1, 1, 1); // => 4

Signature: _.binary(fun:Function)

Returns a new function which accepts only two arguments and passes these arguments to fun . Additional arguments are discarded.

function addAll() { var sum = 0; for (var i = 0; i < arguments.length; i++) { sum = sum + arguments[i]; } return sum; } var add2 = _.binary(addAll); add2(1, 1); // => 2 add2(1, 1, 1, 1); // => 2

Signature: _.curry(func:Function[, reverse:Boolean])

Returns a curried version of func . If reverse is true, arguments will be processed from right to left.

function add3 (x, y, z) { return x + y + z; } var curried = _.curry(add3); // => function curried(1); // => function curried(1)(2); // => function curried(1)(2)(3); // => 6

Signature: _.curry2(fun:Function)

Returns a curried version of func , but will curry exactly two arguments, no more or less.

function add2 (a, b) { return a + b; } var curried = _.curry2(add2); // => function curried(1); // => function curried(1)(2); // => 3

Signature: _.curry3(fun:Function)

Returns a curried version of func , but will curry exactly three arguments, no more or less.

function add3 (a, b, c) { return a + b + c; } var curried = _.curry3(add3); // => function curried(1); // => function curried(1)(2); // => function curried(1)(2)(3); // => 6

Signature: _.fix(fun:Function[, value:Any...])

Fixes the arguments to a function based on the parameter template defined by the presence of values and the _ placeholder.

function add3 (a, b, c) { return a + b + c; } var fixedFirstAndLast = _.fix(add3, 1, _, 3); // => function fixedFirstAndLast(2); // => 6 fixedFirstAndLast(10); // => 14

Signature: _.quaternary(fun:Function)

Returns a new function which accepts only four arguments and passes these arguments to fun . Additional arguments are discarded.

function addAll() { var sum = 0; for (var i = 0; i < arguments.length; i++) { sum = sum + arguments[i]; } return sum; } var add4 = _.quaternary(addAll); add4(1, 1, 1, 1); // => 4 add4(1, 1, 1, 1, 1, 1); // => 4

Signature: _.ternary(fun:Function)

Returns a new function which accepts only three arguments and passes these arguments to fun . Additional arguments are discarded.

function addAll() { var sum = 0; for (var i = 0; i < arguments.length; i++) { sum = sum + arguments[i]; } return sum; } var add3 = _.ternary(addAll); add3(1, 1, 1); // => 3 add3(1, 1, 1, 1, 1, 1); // => 3

Signature: _.unary(fun:Function)

Returns a new function which accepts only one argument and passes this argument to fun . Additional arguments are discarded.

function logArgs() { console.log(arguments); } var logOneArg = _.unary(logArgs); logOneArg("first"); // => ["first"] logOneArg("first", "second"); // => ["first"]

Signature: _.rCurry(func:Function)

Returns a curried version of func where arguments are processed from right to left.

function divide (a, b) { return a / b; } var curried = _.rCurry(divide); // => function curried(1); // => function curried(1)(2); // => 2 curried(2)(1); // => 0.5

Signature: _.rcurry2(func:Function)

Returns a curried version of func where a maxium of two arguments are processed from right to left.

function concat () { var str = ""; for (var i = 0; i < arguments.length; i++) { str = str + arguments[i]; } return str; } var curried = _.rcurry2(concat); // => function curried("a"); // => function curried("a")("b"); // => "ba"

Signature: _.rcurry3(func:Function)

Returns a curried version of func where a maxium of three arguments are processed from right to left.

function concat () { var str = ""; for (var i = 0; i < arguments.length; i++) { str = str + arguments[i]; } return str; } var curried = _.rcurry3(concat); // => function curried("a"); // => function curried("a")("b"); // => function curried("a")("b")("c"); // => "cba"

Functions that are combinators.

Signature: _.always(value:Any)

Aliases: _.k

Takes value and returns a function that will always return value .

var platonicForm = _.always("Eternal & Unchangeable"); platonicForm(); // => "Eternal & Unchangeable"

Signature: _.bound(obj:Object, fname:String)

Returns function property of an object by name, bound to object.

var aristotle = { name: "Aristotle", telos: "flourishing", stateTelos: function() { return this.name + "'s telos is " + this.telos; } }; var stateAristotlesTelos = _.bound(aristotle, "stateTelos"); stateAristotlesTelos(); // => "Aristotle's Telos is flourishing"

Signature: _.comparator(fun:Function)

Takes a binary predicate-like function and returns a comparator function (return values of -1 , 0 , 1 ) which can be used as a callback for _.sort or Array.prototype.sort .

var lessOrEqual = function(x, y) { return x <= y; }; var arr = [0, 1, -2]; arr.sort(_.comparator(lessOrEqual)); // => [-2, 0, 1]

Signature: _.complement(pred:Function)

Returns a function that reverses the sense of a given predicate-like.

function isAugustine (val) { return val === "Augustine"; } isNotAugustine = _.complement(isAugustine); isNotAugustine("Dionysius"); // => True

Signature: _.conjoin(pred:Function...)

Composes multiple predicates into a single predicate that checks all elements of an array for conformance to all of the original predicates.

function startsWithA (val) { return val[0] === "A"; } function endsWithE (val) { return val[val.length - 1] === "e"; } var names = ["Aristotle", "Aquinas", "Plato", "Augustine"]; var startsAAndEndsE = _.conjoin(startsWithA, endsWithE); startsAAndEndsE(names); // => ["Aristotle", "Augustine"]

Signature: _.disjoin(pred:Function...)

Composes multiple predicates into a single predicate that checks all elements of an array for conformance to any of the original predicates.

function startsWithA (val) { return val[0] === "A"; } function endsWithE (val) { return val[val.length - 1] === "e"; } var names = ["Aristotle", "Aquinas", "Plato", "Augustine"]; var startsAOrEndsE = _.disjoin(startsWithA, endsWithE); startsAOrEndsE(names); // => ["Aristotle", "Aquinas", "Augustine"]

Signature: _.juxt(fun:Function...)

Returns a function whose return value is an array of the results of calling each of the original functions with the arguments.

function firstChar (val) { return val[0]; } function lastChar (val) { return val[val.length - 1]; } var firstAndLastChars = _.juxt(firstChar, lastChar); firstAndLastChars("Etruria"); // => ["E", "a"]

Signature: _.flip(fun:Function)

Returns a function that works identically to fun , but accepts the arguments in reverse order.

function regionCapitol (region, capitol) { return "The capitol of " + region + " is " + capitol; } capitolRegion = _.flip(regionCapitol); capitolRegion("Thessalonica", "Illyrica"); // => "The capitol of Illyrica is Thessalonica"

Signature: _.flip2(fun:Function)

Returns a function that works identically to fun , but accepts the first two arguments in reverse order. The order of all other arguments remains the same.

function regionCapitol (region, capitol) { return "The capitol of " + region + " is " + capitol; } capitolRegion = _.flip2(regionCapitol); capitolRegion("Thessalonica", "Illyrica"); // => "The capitol of Illyrica is Thessalonica"

Signature: _.fnull(fun:Function[, default:Any...])

Returns a function that protects fun from receiving non-existy values. Each subsequent value provided to fnull acts as the default to the original fun should a call receive non-existy values in the defaulted arg slots.

function getLength (val) { return val.length; } safeGetLength = _.fnull(getLength, []); safeGetLength([1, 2, 3]); // => 3 safeGetLength(null); // => 0

Signature: _.functionalize(fun:Function[, default:Any...])

Takes a method-style function (one which uses this ) and pushes this into the argument list. The returned function uses its first argument as the receiver/context of the original function, and the rest of the arguments are used as the original's entire argument list.

var militaryUnits = { centuria: "80 men", cohort: "480 men", getDescription: function (unitName) { return this[unitName]; } }; var getDescription = _.functionalize(militaryUnits.getDescription); var rulers = { Leonidas: "King of Sparta", Augustus: "First Roman Emperor" }; getDescription(rulers, "Augustus"); // => "First Roman Emperor"

Signature: _.mapArgs(fun:Function)

Takes a target function and returns a new function which accepts a mapping function, which in turn returns a function that will map its arguments before calling the original target function.

function doubleNum (x) { return 2 * x; } function squareNum (x) { return x * x; } var squareThenDouble = _.mapArgs(doubleNum)(squareNum); squareThenDouble(3); // => 18

Signature: _.mapArgs(mapFun:Function)

Takes a mapping function and returns a new combinator function which will take a target function and return a new version which maps its arguments with the mapping function before executing the body of the target function.

function doubleNum (x) { return 2 * x; } function squareNum (x) { return x * x; } var squareArgs = _.mapArgsWith(squareNum); var squareThenDouble = squareArgs(doubleNum); squareThenDouble(3); // => 18

Signature: _.methodize(func:Function)

Takes a function and pulls the first argument out of the argument list and into this position. The returned function calls the original with its receiver ( this ) prepending the argument list. The original is called with a receiver of null .

function describe (obj) { return obj.name + ": " + obj.description; } var democritus = { name: "Democritus", description: "originator of the atomic hypothesis", describe: _.methodize(describe) }; democritus.describe(); // => "Democritus: originator of the atomic hypothesis"

Signature: _.pipeline(func:Function[, func2:Function...]) or _.pipeline(funcArr:Array)

Aliases: _.t

Takes a list of functions, either as an array or as individual arguments and returns a function that takes some value as its first argument and runs it through a pipeline of the original functions given.

function halveNum (x) { return x / 2; }; function squareNum (x) { return x * x; }; function doubleNum (x) { return 2 * x; }; var halveSquareDouble = _.pipeline(halveNum, squareNum, doubleNum); halveSquareDouble(1); // => 0.5 var doubleSquareHalve = _.pipeline([doubleNum, squareNum, halveNum]); doubleSquareHalve(1); // => 2

Signature: _.splat(fun:Function)

Takes a function expecting one or more arguments and returns a function that takes an array and uses its elements as the arguments to the original function. This roughly corresponds to the spread operator in ECMAScript 6.

function listTwoNames (a, b) { return a.name + " & " + b.name; } var listTwoNamesFromArray = _.splat(listTwoNames); listTwoNamesFromArray([{ name: "Zeno" }, { name: "Parmenides"}]); // => "Zeno & Parmenides"

Signature: _.unsplat(fun:Function)

Aliases: _.unsplatr

Takes a function expecting an array as its last argument and returns a function which works identically, but takes a list of trailing arguments instead. Roughly corresponds to rest parameters in ECMAScript 6.

function joinWith (joiner, arr) { return arr.join(joiner); } var joinArgsWith = _.unsplat(joinWith); joinArgsWith(" & ", "Plutarch", "Proclus"); // => "Plutarch & Proclus"

Signature: _.unsplatl(fun:Function)

Similar to unsplat, but takes a function expecting an array as its first argument and returns a function which works identically, but takes a list of leading arguments instead. Roughly corresponds to rest parameters in ECMAScript 6.

function joinWith (arr, joiner) { return arr.join(joiner); } var joinArgsWith = _.unsplat(joinWith); joinArgsWith("Olympiodorus", "Syrianus", " & "); // => "Olympiodorus & Syrianus"

Functions to iterate over collections.

Signature: _.iterators.accumulate(iter:Function, binaryFn:Function, initial:Any)

Returns a function that when called will iterate one step with iter and return the value currently accumulated by using binaryFn . The function will return undefined once all values have been iterated over.

var generalsIterator = _.iterators.List(["Hannibal", "Scipio"]); function countLetters(memo, element) { return memo + element.length; } var generalsAcc = _.iterators.accumulate(generalsIterator, countLetters, 0); generalsAcc(); // => 8 generalsAcc(); // => 14 generalsAcc(); // => undefined

Signature: _.iterators.accumulateWithReturn(iter:Function, binaryFn:Function, initial:Any)

Acts similarly to accumulate, except that binaryFn is expected to return an array of two elements. The value of the first element is given to the next run of binaryFn . The value of the second element is yielded by the iterator.

var fiveIter = _.iterators.List([1, 2, 3, 4, 5]); function adderWithMessage (state, element) { return [state + element, 'Total is ' + (state + element)]; } var i = _.iterators.accumulateWithReturn(fiveIter, adderWithMessage, 0); i(); // => "Total is 1" i(); // => "Total is 3" i(); // => "Total is 6"

Signature: _.iterators.drop(iter:Function[, numberToDrop:Number])

Given an iterator function iter , will return a new iterator which iterates over the same values as iter , except that the first numberToDrop values will be omitted. If numberToDrop is not provided, it will default to 1 .

var deityIter = _.iterators.List(["Zeus", "Apollo", "Athena", "Aphrodite"]); var goddessIter = _.iterators.drop(deityIter, 2); goddessIter(); // => "Athena" goddessIter(); // => "Aphrodite"

Signature: _.iterators.foldl(iter:Function, binaryFn:Function[, seed:Any])

Aliases: iterators.reduce

Boils down the values given by iter into a single value. The seed is the initial state. The binaryFn is given two arguments: the seed and the current value yielded by iter .

var sybylIter = _.iterators.List(["cumaean", "tiburtine"]); function commaString (a, b) { return a + ", " + b; } _.iterators.foldl(sybylIter, commaString); // => "cumaean, tiburtine"

Signature: _.iterators.K(value:Any)

Aliases: iterators.constant

Returns a function that when invoked will always return value .

var ceasar = _.iterators.K("Ceasar"); ceasar(); // => "ceasar"

Signature: _.iterators.List(array:Array)

Returns an iterater that when invoked will iterate over the contents of array .

var triumvirIter = _.iterators.List(["Ceasar", "Pompey", "Crassus"]; triumvirIter(); // => "Ceasar" triumvirIter(); // => "Pompey" triumvirIter(); // => "Crassus"

Signature: _.iterators.map(iter:Function, unaryFn:Function)

Returns a new iterator function which on each iteration will return the result of running iter 's current value through unaryFn .

var notablesIter = _.iterators.List(["Socrates", "Plato"]); function postfixAthenian (val) { return val + ", Athenian"; } var notableAtheniansIter = _.iterators.map(notablesIter, postfixAthenian); notableAtheniansIter(); // => "Socrates, Athenian" notableAtheniansIter(); // => "Plato, Athenian"

Signature: _.iterators.mapcat(iter:Function, unaryFn:Function)

Returns an iterator which is the result of flattening the contents of iter , and mapping the results with unaryFn .

function naturalSmallerThan (x) { return _.iterators.List(_.range(0, x)); } var treeIter = _.iterators.Tree([1, [2]]); var smallerThanIter = _.iterators.mapcat(treeIter, naturalSmallerThan); smallerThanIter(); // => 0 smallerThanIter(); // => 0 smallerThanIter(); // => 1

Signature: _.iterators.numbers([start:Number])

Returns an iterator of integers which will begin with start and increment by one for each invocation. If start is not provided it will default to 1 .

var twoAndUp = _.iterators.numbers(2); twoAndUp(); // => 2 twoAndUp(); // => 3 twoAndUp(); // => 4

Signature: `_.iterators.range([from:Number, to:Number, by:Number]);

Returns an iterator whose values consist of numbers beginning with from , ending with to , in steps of size by .

var by5 = _.iterators.range(5, Infinity, 5); by5(); // => 5 by5(); // => 10 by5(); // => 15

Signature: _.iterators.reject(iter:Function, unaryPredicatFn:Function)

Returns an iterator consisting of the values of iter which are not flagged true by unaryPredicateFn .

var philosophers = ["Anaximander", "Socrates", "Heraclitus"]; var philosophersIter = _.iterators.List(philosophers); function isSocrates (val) { return val === "Socrates"; } var preSocraticsIter = _.iterators.reject(philosophersIter, isSocrates); preSocraticsIter() // => "Anaximander" preSocraticsIter() // => "Heraclitus"

Signature: _.iterators.select(iter:Function, unaryPredicatFn:Function)

Aliases: iterators.find , iteraters.filter

Returns an iterator consisting of the values of iter which are flagged true by unaryPredicateFn .

var philosophers = ["Anaximander", "Socrates", "Heraclitus"]; var philosophersIter = _.iterators.List(philosophers); function isSocrates (val) { return val === "Socrates"; } var socraticIter = _.iterators.select(philosophersIter, isSocrates); socraticIter() // => "Socrates"

Signature: _.iterators.slice(iter:Function, numberToDrop:Number, numberToTake:Number)

Returns an iterator whose values consist of iter 's after removing numberToDrop from the head, and a maxiumum of numberToTake of the remaining. If numberToTake is not specified, all of iter 's remaining values will be used.

var emperors = ["Augustus", "Tiberius", "Caligula", "Claudius"]; var emperorsIter = _.iterators.List(emperors); var middleEmperorsIter = _.iterators.slice(emperorsIter, 1, 2); middleEmperorsIter(); // => "Tiberius" middleEmperorsIter(); // => "Caligula" middleEmperorsIter(); // => undefined

Signature: _.iterators.take(iter:Function[, numberToTake:Number])

Returns an iterator consisting of the first numberToTake values yielded by iter . If numberToTake is not provided, it will default to 1 .

var byzantineEmperors = ["Constantine", "Constantius", "Constans"]; var byzantineEmperorsIter = _.iterators.List(byzantineEmperors); var firstTwoEmperorsIter = _.iterators.take(byzantineEmperorsIter, 2); firstTwoEmperorsIter(); // => "Constantine" firstTwoEmperorsIter(); // => "Constantius" firstTwoEmperorsIter(); // => undefined

Signature: _.iterators.Tree(array:Array);

Returns an iterator that yields the individual values of a tree array .

var rulers = ["Augustus", ["Constantine"], ["Leo", ["Charlemagne"]]]; var rulersIter = _.iterators.Tree(rulers); rulersIter(); // => "Augustus" rulersIter(); // => "Constantine" rulersIter(); // => "Leo" rulersIter(); // => "Charlemagne"

Signature: _.iterators.unfold(seed:Any, unaryFn:Function)

function greatify (val) { return val + " the Great"; } var greatIter = _.iterators.unfold("Constantine", greatify); greatIter(); // => "Constantine the Great" greatIter(); // => "Constantine the Great the Great" greatIter(); // => "Constantine the Great the Great the Great"

Signature: _.iterators.unfold(seed:Any, unaryFn:Function)

Acts similarly to unfold, except that unaryFn is expected to return an array with two elements. The value of the first element is given to the next run of unaryFn . The value of the second element is yielded by the iterator.

var i = _.iterators.unfoldWithReturn(1, function(n) { return [n + 1, n * n]; }); i(); // => 1 i(); // => 4 i(); // => 9

Functions which return whether the input meets a condition.

Signature: isAssociative(value:Any)

Returns a boolean indicating whether or not the value is an associative object. An associative object is one where its elements can be accessed via a key or index (e.g. arrays, arguments , objects).

_.isAssociative(["Athens", "Sparta"]); // => true _.isAssociative(42); // => false

Signature: _.isDecreasing(values:Any...)

Checks whether the arguments are monotonically decreasing values (i.e. whether each argument is less than the previous argument.)

_.isDecreasing(3, 2, 1); // => true _.isDecreasing(15, 12, 2); // => true _.isDecreasing(2, 3); // => false

Signature: _.isEven(value:Any)

Checks whether the value is an even number.

_.isEven(12); // => true _.isEven(3); // => false _.isEven({}); // => false

Signature: _.isFloat(value:Any)

Checks whether the value is a "float." For the purposes of this function, a float is a numeric value that is not an integer. A numeric value may be a number, a string containing a number, a Number object, etc.

NOTE: JavaScript itself makes no distinction between integers and floats. For the purposes of this function both 1 and 1.0 are considered integers.

_.isFloat(1.1); // => true _.isFloat(1); // => false _.isFloat(1.0); // => false _.isFloat("2.15"); // => true

Signature: _.isIncreasing(value:Any...)

Checks whether the arguments are monotonically increasing values (i.e. each argument is greater than the previous argument.)

_.isIncreasing(1, 12, 15); // => true _.isIncreasing(1); // => true _.isIncreasing(5, 4); // => false

Signature: _.isIndexed(value:Any)

Checks whether the value is "indexed." An indexed value is one which accepts a numerical index to access its elements. (e.g. arrays and strings)

NOTE: Underscore does not support cross-browser consistent use of strings as array-like values, so be wary in IE 8 when using string objects and in IE7 and earlier when using string literals & objects.

_.isIndexed("Socrates"); // => true _.isIndexed({poison: "hemlock"}); // => false

Signature: _.isInstanceOf(value:Any, constructor:Function)

Checks whether the value is an instance of the constructor.

_.isInstanceOf(new Date(), Date); // => true _.isInstanceOf("Hippocrates", RegExp); // => false

Signature: _.isInteger(value:Any)

Checks whether the value is a numeric integer. A numeric value can be a string containing a number, a Number object, etc.

_.isInteger(18); // => true _.isInteger("18"); // => true _.isInteger(2.5); // => false _.isInteger(-1); // => true

Signature: _.isJSON(value:Any)

Checks whether the value is valid JSON. See the spec for more information on what constitutes valid JSON.

NOTE: This function relies on JSON.parse which is not available in IE7 and earlier.

_.isJSON('{ "name": "Crockford" }'); // => true _.isJSON({ name: "Crocket" }); // => false

Signature: _.isNegative(value:Any)

Checks whether the value is a negative number.

_.isNegative(-2); // => true _.isNegative(5); // => false

Signature: _.isNumeric(value:Any)

A numeric is something that contains a numeric value, regardless of its type. It can be a string containing a numeric value, exponential notation, a Number object, etc.

_.isNumeric("14"); // => true _.isNumeric("fourteen"); // => false

Signature: _.isOdd(value:Any)

Checks whether the value is an odd number.

_.isOdd(3); // => true _.isOdd(2); // => false _.isOdd({}); // => false

Signature: _.isPlainObject(value:Any);

Checks whether the value is a "plain" object created as an object literal ( {} ) or explicitly constructed with new Object() . Instances of other constructors are not plain objects.

_.isPlainObject({}); // => true _.isPlainObject(new Date()); // => false _.isPlainObject([]); // => false

Signature: _.isPositive(value:Any)

Checks whether the value is a positive number.

_.isPositive(21); // => true _.isPositive(-3); // => false

Signature: _.isSequential(value:Any)

Checks whether the value is a sequential composite type (i.e. arrays and arguments ).

_.isSequential(["Herodotus", "Thucidydes"); // => true _.isSequential(new Date); // => false

Signature: _.isValidDate(value:Any)

Checks whether the value is a valid date. That is, the value is both an instance of Date and it represents an actual date.

Warning: This function does not verify whether the original input to Date is a real date. For instance, new Date("02/30/2014") is considered a valid date because Date coerces that into a representation of 03/02/2014. To validate strings representing a date, consider using a date/time library like Moment.js.

_.isValidDate(new Date("January 1, 1900")); // => true _.isValidDate(new Date("The Last Great Time War")); // => false

Signature: _.isZero(value:Any)

Checks whether the value is 0 .

_.isZero(0); // => true _.isZero("Pythagoras"); // => false

Functions to build objects.

Signature: _.frequencies(arr:Array)

Returns an object whose property keys are the values of arr 's elements. The property values are a count of how many times that value appeared in arr .

var citations = ["Plato", "Aristotle", "Plotinus", "Plato"]; _.frequencies(citations); // => { Plato: 2, Aristotle: 1, Plotinus: 1 }

Signature: _.merge(obj1:Object[, obj:Object...])

Merges two or more objects starting with the left-most and applying the keys rightward.

_.merge({ a: "alpha" }, { b: "beta" }); // => { a: "alpha", b: "beta" }

Signature: _.renameKeys(obj:Object, keyMap:Object)

Takes an object ( obj ) and a map of keys ( keyMap ) and returns a new object where the keys of obj have been renamed as specified in keyMap .

_.renameKeys({ a: 1, b: 2 }, { a: "alpha", b: "beta" }); // => { alpha: 1, beta: 2 }

Signature: _.setPath(obj:Object, value:Any, ks:Array, defaultValue:Any)

Sets the value of a property at any depth in obj based on the path described by the ks array. If any of the properties in the ks path don't exist, they will be created with defaultValue .

_.setPath({}, "Plotinus", ["Platonism", "Neoplatonism"], {}); // => { Platonism: { Neoplatonism: "Plotinus" } }

Signature: _.snapshot(obj:Object)

Snapshots/clones an object deeply.

var schools = { plato: "Academy", aristotle: "Lyceum" }; _.snapshot(schools); // => { plato: "Academy", aristotle: "Lyceum" } schools === _.snapshot(schools); // => false

Signature: _.updatePath(obj:Object, fun:Function, ks:Array, defaultValue:Any)

Updates the value at any depth in a nested object based on the path described by the ks array. The function fun is called with the current value and is expected to return a replacement value. If no keys are provided, then the object itself is presented to fun . If a property in the path is missing, then it will be created with defaultValue .

var imperialize = function (val) { if (val == "Republic) return "Empire"; else return val; }; _.updatePath({ rome: "Republic" }, imperialize, ["rome"]); // => { rome: "Empire" }

Functions to select values from an object.

Signature: _.accessor(field:String)

Returns a function that will attempt to look up a named field in any object that it is given.

var getName = _.accessor('name'); getName({ name: 'Seneca' }); // => 'Seneca'

Signature: _.dictionary(obj:Object)

Given an object, returns a function that will attempt to look up a field that it is given.

var generals = { rome: "Scipio", carthage: "Hannibal" }; var getGeneralOf = _.dictionary(generals); getGeneralOf("rome"); // => "Scipio"

Signature: _.getPath(obj:Object, ks:String|Array)

Gets the value at any depth in a nested object based on the path described by the keys given. Keys may be given as an array or as a dot-separated string. Returns undefined if the path cannot be reached.

var countries = { greece: { athens: { playwright: "Sophocles" } } } }; _.getPath(countries, "greece.athens.playwright"); // => "Sophocles" _.getPath(countries, "greece.sparta.playwright"); // => undefined _.getPath(countries, ["greece", "athens", "playwright"]); // => "Sophocles" _.getPath(countries, ["greece", "sparta", "playwright"]); // => undefined

Signature: _.hasPath(obj:Object, ks:String|Array)

Returns a boolean indicating whether there is a property at the path described by the keys given. Keys may be given as an array or as a dot-separated string.

var countries = { greece: { athens: { playwright: "Sophocles" } } } }; _.hasPath(countries, "greece.athens.playwright"); // => true _.hasPath(countries, "greece.sparta.playwright"); // => false _.hasPath(countries, ["greece", "athens", "playwright"]); // => true _.hasPath(countries, ["greece", "sparta", "playwright"]); // => false

Signature: _.kv(obj:Object, key:String)

Returns the key/value pair for a given property in an object, undefined if not found.

var playAuthor = { "Medea": "Aeschylus" }; _.kv(playAuthor, "Medea"); // => ["Medea", "Aeschylus"] _.kv(playAuthor, "Hamlet"); // => undefined

Signature: _.omitWhen(obj, pred:Function)

Returns a copy of obj omitting any properties that the predicate ( pred ) function returns true for. The predicat function is invoked with each property value, like so: pred(propValue) .

var playwrights = { euripedes: "Greece", shakespere: "England" }; _.omitWhen(obj, function (country) { return country == "England" }); // => { euripedes: "Greece" }

Signature: _.pickWhen(obj:Object, pred:Function)

Returns a copy of obj containing only properties that the predicate ( pred ) function returns true for. The predicate function is invoked with each property value, like so: pred(propValue) .

var playwrights = { euripedes: "Greece", shakespere: "England" }; _.pickWhen(obj, function (country) { return country == "England" }); // => { shakespeare: "England" }

Signature: `_.selectKeys(obj:Object, ks:Array);

Returns a copy of obj containing only the properties listed in the ks array.

var philosopherCities = { Philo: "Alexandria", Plato: "Athens", Plotinus: "Rome" } _.selectKeys(philosopherCities, ["Plato", "Plotinus"]); // => { Plato: "Athens", Plotinus: "Rome" }

Functions which deal with whether a value "exists."

Signature: _.exists(value:Any)

Checks whether or not the value is "existy." Both null and undefined are considered non-existy values. All other values are existy.

_.exists(null); // => false _.exists(undefined); // => false _.exists({}); // = > true _.exists("Sparta"); // => true

Signature: _.falsey(value:Any)

Checks whether the value is falsey. A falsey value is one which coerces to false in a boolean context.

_.falsey(0); // => true _.falsey(""); // => true _.falsey({}); // => false _.falsey("Corinth"); // => false

Signature: _.firstExisting(value:Any[, value:Any...])

Returns the first existy argument from the argument list.

_.firstExisting("Socrates", "Plato"); // => "Socrates" _.firstExisting(null, undefined, "Heraclitus"); // => "Heraclitus"

Signature: _.not(value:Any)

Returns a boolean which is the opposite of the truthiness of the original value.

_.not(0); // => true _.not(1); // => false _.not(true); // => false _.not(false); // => true _.not({}); // => false _.not(null); // => true

Signature: _.truthy(value:Any)

Checks whether the value is truthy. A truthy value is one which coerces to true in a boolean context.

_.truthy({}); // => true _.truthy("Athens"); // => true _.truthy(0); // => false _.truthy(""); // => false

Functions which wrap JavaScript's operators.

Signature: _.add(value:Number, value:Number[, value:Number...])

Returns the sum of the arguments.

_.add(1, 2, 3, 4); // => 10

Signature: _.bitwiseAnd(value:Any, value:Any[, value:Any...])

Returns the result of using the & operator on the arguments.

_.bitwiseAnd(1, 3); // => 1 _.bitwiseAnd(1, 3, 2); // => 0

Signature: _.bitwiseLeft(value:Any, value:Any[, value:Any...])

Returns the result of using the << operator on the arguments.

_.bitwiseLeft(1, 3); // => 8 _.bitwiseLeft(1, 3, 2); // => 32

Signature: _.bitwiseRight(value:Any, value:Any[, value:Any...])

Returns the result of using the >> operator on the arguments.

_.bitwiseRight(3, 1); // => 1 _.bitwiseRight(3, 1, 3); // => 0

Signature: _.bitwiseNot(value:Any)

Returns the result of using the ~ operator on the value.

_.bitwiseNot(1); // => -2 _.bitwiseOr(2); // => -3

Signature: _.bitwiseOr(value:Any, value:Any[, value:Any...])

Returns the result of using the | operator on the arguments.

_.bitwiseOr(1, 3); // => 3 _.bitwiseOr(1, 3, 4); // => 7

Signature: _.bitwiseXor(value:Any, value:Any[, value:Any...])

Returns the result of using the ^ operator on the arguments.

_.bitwiseXor(1, 3); // => 2 _.bitwiseXor(1, 3, 3); // => 1

Signature: _.bitwiseZ(value:Any, value:Any[, value:Any...])

Returns the result of using the >>> operator on the arguments.

_.bitwiseZ(72, 32); // => 72 _.bitwiseZ(72, 32, 2); // => 18

Signature: _.dec(value:Number)

Returns the result of decrementing the value by 1 .

_.dec(2); // => 1

Signature: _.div(value:Number, value:Number[, value:Number...])

Returns the quotient of the arguments.

_.div(8, 2); // => 4 _.div(8, 2, 2); // => 2

Signature: _.eq(value:Any, value:Any[, value:Any...])

Compares the arguments with loose equality ( == ).

_.eq(1, "1"); // => true _.eq(1, 15); // => false _.eq(1, true, "1"); // => true _.eq(1, 1, 15); // => false

Signature: _.gt(value:Any, value:Any[, value:Any...])

Checks whether each argument is greater than the previous argument.

_.gt(1, 2); // => true _.gt(1, 2, 3); // => true _.gt(1, 6, 2); // => false

Signature: _.gte(value:Any, value:Any[, value:Any...])

Checks whether each argument is greater than or equal to the previous argument.

_.gte(1, 2); // => true _.gte(1, 1, 3); // => true _.gte(1, 6, 2); // => false

Signature: _.inc(value:Number)

Returns the result of incrementing the value by 1 .

_.inc(2); // => 3

Signature: _.lt(value:Any, value:Any[, value:Any...])

Checks whether each argument is less than the previous argument.

_.lt(2, 1); // => true _.lt(2, 1, 0); // => true _.lt(2, 1, 12); // => false

Signature: _.lte(value:Any, value:Any[, value:Any...])

Checks whether each argument is less than or equal to the previous argument.

_.lte(2, 1); // => true _.lte(2, 1, 1); // => true _.lte(2, 1, 12); // => false

Signature: _.mul(value:Number, value:Number[, value:Number...])

Returns the product of the arguments.

_.mul(1, 2, 3, 4); // => 24

Signature: _.mod(dividend:Number, divisor:Number)

Returns the remainder of dividing dividend by divisor .

_.mod(26, 5); // => 1 _.mod(14, 3); // => 2

Signature: _.neg(num:Number)

Returns a new number with the opposite sign value of num .

_.neg(5); // => -5 _.neg(-3); // => 3

Signature: _.neq(value:Any, value:Any[, value:Any...])

Checks whether each argument is not equal to the previous argument, using loose inequality ( != ).

_.neq(2, 1); // => true _.neq(2, 1, 1); // => true _.neq(1, 1); // => false

Signature: _.not(value:Any)

Returns a boolean which is the opposite of the truthiness of the original value.

_.not(0); // => true _.not(1); // => false _.not(true); // => false _.not(false); // => true _.not({}); // => false _.not(null); // => true

Signature: _.seq(value:Any, value:Any[, value:Any...])

Checks whether the arguments are strictly equal ( === ) to each other.

_.seq(2, 2); // => true _.seq(2, "2"); // => false _.seq(2, 2, 2); // => true

Signature: _.sneq(value:Any, value:Any[, value:Any...])

Checks whether the arguments are strictly not equal ( !== ) to each other.

_.sneq(2, 2); // => false _.sneq(2, "2"); // => true _.sneq(2, 2, 2); // => false

Signature: _.sub(value:Number, value:Number[, value:Number...])

Returns the difference of the arguments.

_.sub(10, 3); // => 7 _.sub(10, 3, 5); // => 2

Functions for working with strings.

Signature: _.camelCase(string:String)

Converts a dash-separated string to camel case. Opposite of toDash.

_.camelCase("ancient-greece"); // => "ancientGreece"

Signature: _.explode(s:String)

Explodes a string into an array of characters. Opposite of implode.

_.explode("Plato"); // => ["P", "l", "a", "t", "o"]

Signature: _.fromQuery(str:String)

Takes a URL query string and converts it into an equivalent JavaScript object. Opposite of toQuery

_.fromQuery("forms%5Bperfect%5D=circle&forms%5Bimperfect%5D=square"); // => { forms: { perfect: "circle", imperfect: "square" } }

Signature: _.implode(a:Array)

Implodes an array of strings into a single string. Opposite of explode.

_.implode(["H", "o", "m", "e", "r"]); // => "Homer"

Signature: _.strContains(str:String, search:String)

Reports whether a string contains a search string.

_.strContains("Acropolis", "polis"); // => true

Signature: _.toDash(string:String)

Converts a camel case string to a dashed string. Opposite of camelCase.

_.toDash("thisIsSparta"); // => "this-is-sparta"

Signature: _.toQuery(obj:Object)

Takes an object and converts it into an equivalent URL query string. Opposite of fromQuery.

_.toQuery({ forms: { perfect: "circle", imperfect: "square" } }); // => "forms%5Bperfect%5D=circle&forms%5Bimperfect%5D=square"

Trampoline functions.

Signature: _.done(value:Any)

A utility for wrapping a function's return values so they can be used by _.trampoline . See below.

Signature: _.trampoline(fun:Function[, args:Any...])

Provides a way of creating recursive functions that won't exceed a JavaScript engine's maximum recursion depth. Rather than writing a naive recursive function, the function's base cases must return _.done(someValue) , and recursive calls must be wrapped in a returned function.

In order to create a trampolined function that can be used in the same way as a naive recursive function, use _.partial as illustrated below.

function isEvenNaive (num) { if (num === 0) return true; if (num === 1) return false; return isEvenNaive(num - 2); } isEvenNaive(99999); // => InternalError: too much recursion function isEvenInner (num) { if (num === 0) return _.done(true); if (num === 1) return _.done(false); return function () { return isEvenInner(Math.abs(num) - 2); }; } _.trampoline(isEvenInner, 99999); // => false var isEven = _.partial(_.trampoline, isEvenInner); isEven(99999); // => false