Underscorejs

javascript-libraries

Resources

http://net.tutsplus.com/tutorials/javascript-ajax/getting-cozy-with-underscore-js/ - done reading

Why should I consider using Underscore?

Underscore has methods for working with collections, arrays, functions, objects, and a number of utility methods. In other words, Underscore has methods for almost everything, including template.

Underscore is a JavaScript library that provides a whole mess of useful functional programming helpers without extending any built-in objects. Underscore provides over 100 functions that support both your favorite workaday functional helpers such as map, filter, invoke, as well as more specialized goodies such as function binding, javascript templating, creating quick indexes, deep equality testing, and so on.

If your front-end code is simple (just DOM manipulation), then perhaps you do not need to use Underscore. Underscore provides a lot of methods that you may find useful from time to time, but if you are in an environment where bandwidth is limited (mobile), and if there is no way to store Underscore permantly onto the mobile device, and you really want to reduce the bandwidth, you may want to see if the other libraries that you currently use already provide whatever functionality that you need from Underscore. If you just need a couple of method from Underscore, you can implement those methods yourself. If bandwidth is not a concern, or if you've figure out a way to store the Underscore code onto the mobile device, go ahead and use Underscore. The compressed download of Underscore is only about 4kb (I heard). Of course, you can use Underscore for back-end development if you are using Node.

What are some of the methods used for working with collections?

  • each
  • map
  • reduce
  • find: 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.
  • filter: Looks through each value in the list, returning an array of all the values that pass a truth test (predicate).
  • where
  • findWhere
  • reject
  • every
  • some
  • contains
  • invoke
  • pluck
  • max
  • min
  • sortBy
  • groupBy
  • indexBy
  • countBy
  • shuffle
  • sample
  • toArray
  • size
  • partition
  • ...

What are some of the methods used for working with array?

  • first
  • initial
  • last
  • rest
  • compact
  • flatten
  • without
  • union
  • intersection
  • difference
  • uniq
  • zip
  • object
  • indexOf
  • lastIndexOf
  • sortedIndex
  • range

What are some of the methods used for working with functions?

  • partial
  • memoize
  • bind
  • bindAll
  • delay
  • defer
  • throttle
  • debounce
  • once: Creates a version of the function that can only be called one time. Repeated calls to the modified function will have no effect, returning the value from the original call. Useful for initialization functions, instead of having to set a boolean flag and then check it later.
  • after: Creates a version of the function that will only be run after first being called count times. Useful for grouping asynchronous responses, where you want to be sure that all the async calls have finished, before proceeding.
  • before: Creates a version of the function that can be called no more than count times. The result of the last function call is memoized and returned when count has been reached.
  • wrap: Wraps the first function inside of the wrapper function, passing it as the first argument. This allows the wrapper to execute code before and after the function runs, adjust the arguments, and execute it conditionally.
  • negate: Returns a new negated version of the predicate function.
  • compose: Returns the composition of a list of functions, where each function consumes the return value of the function that follows. In math terms, composing the functions f(), g(), and h() produces f(g(h())).
  • ...

What are some of the methods used for working with objects?

  • keys
  • values
  • pairs
  • invert
  • functions: Returns a sorted list of the names of every method in an object — that is to say, the name of every function property of the object.
  • extend: Copy all of the properties in the source objects over to the destination object, and return the destination object. It's in-order, so the last source will override properties of the same name in previous arguments.
  • pick: Return a copy of the object, filtered to only have values for the whitelisted keys (or array of valid keys). Alternatively accepts a predicate indicating which keys to pick.
  • omit: Return a copy of the object, filtered to omit the blacklisted keys (or array of keys). Alternatively accepts a predicate indicating which keys to omit.
  • defaults
  • clone
  • tap
  • has
  • matches
  • property
  • isEqual: Performs an optimized deep comparison between the two objects, to determine if they should be considered equal.
  • isEmpty: Returns true if an enumerable object contains no values (no enumerable own-properties). For strings and array-like objects _.isEmpty checks if the length property is 0.
  • isElement: Returns true if object is a DOM element. _.isElement(object)
  • isArray: Returns true if object is an Array. _.isArray(object)
  • isObject: Returns true if value is an Object. Note that JavaScript arrays and functions are objects, while (normal) strings and numbers are not. _.isObject(value)
  • isArguments: Returns true if object is an Arguments object.
  • isFunction: Returns true if object is a Function. _.isFunction(object)
  • isString: Returns true if object is a String. _.isString(object)
  • isNumber: Returns true if object is a Number (including NaN). _.isNumber(object)
  • isFinite: Returns true if object is a finite Number. _.isFinite(object)
  • isBoolean: Returns true if object is either true or false. _.isBoolean(object)
  • isDate: Returns true if object is a Date. _.isDate(object)
  • isRegExp: Returns true if object is a RegExp. _.isRegExp(object)
  • isNaN: Returns true if object is NaN. _.isNaN(object)
  • isNull: Returns true if the value of object is null. _.isNull(object)
  • isUndefined: Returns true if value is undefined. _.isUndefined(value)

What are the utility methods?

  • noConflict: Give control of the "_" variable back to its previous owner. Returns a reference to the Underscore object.
  • identity: Returns the same value that is used as the argument. In math: f(x) = x. This function looks useless, but is used throughout Underscore as a default iteratee.
  • times: Invokes the given iteratee function n times.
  • random: Returns a random integer between min and max, inclusive. If you only pass one argument, it will return a number between 0 and that number.
  • mixin: Allows you to extend Underscore with your own utility functions. Pass a hash of {name: function} definitions to have your functions added to the Underscore object, as well as the OOP wrapper.
  • uniqueId: Generate a globally-unique id for client-side models or DOM elements that need one. If prefix is passed, the id will be appended to it. This function does not generate a GUID.
  • escape: Escapes a string for insertion into HTML
  • unescape: The opposite of escape
  • result: If the value of the named property is a function then invoke it with the object as context; otherwise, return it.
  • now: Returns an integer timestamp for the current time, using the fastest method available in the runtime.
  • template: Use this method to implement client-side templates.

How to do filtering with Underscore?

var scores = [84, 99, 91, 65, 87, 55, 72, 68, 95, 42];
var topScore = [];
var scoreLimit = 90;

topScores = _.select(scores, function(score) { return score > scoreLimit; });

The _.select function, when used as above, takes two arguments. The first argument is an the scores array, and the second argument is a callback function. This function is invoked for each element in the score array, and if the result of this function is true, the item is included in the result.

How to use _ in the "object oriented" fashion?

var scores = [84, 99, 91, 65, 87, 55, 72, 68, 95, 42];
var topScore = [];
var scoreLimit = 90;

topScores = _(scores).select(function(score) { return score > scoreLimit; });

Notice that the scores array is not passed as the first argument to the select function. It is passed as argument to the _() method.

What are the benefits of using Underscore in the "object oriented" fashion?

When used in the "object oriented" fashion, we can use jQuery-esque method chaining.

What is the purpose of the pluck method?

Let's say that we have a little array containing key value pairs and you'd like to extract just a specific property from each:

var tuts = [{name: 'NetTuts', niche: 'Web Development'}, 
    {name: 'WPTuts', niche: 'Wordpress'},
    {name: 'PSDTuts', niche: 'Photoshop'}];
var niches = _.pluck(tuts, 'niche');
console.log(niches);
// ["Web Development", "Wordpress", "Photoshop"]

Using pluck is as simply as passing in the target object or array as well as the property to pick out. So the purpose of pluck is to extract the values of particular property within an array of objects.

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"]

What is the purpose of the map function?

The map function creates an array from a collection where each element can be mutated or otherwise changed:

var Tuts = [{name : 'NetTuts', niche : 'Web Development'}, 
    {name : 'WPTuts', niche : 'WordPress'}, 
    {name : 'PSDTuts', niche : 'PhotoShop'}, 
    {name : 'AeTuts', niche : 'After Effects'}];

var names = _(Tuts).pluck('name').map(function (value){return value + '+'});

console.log(names);

// ["NetTuts+", "WPTuts+", "PSDTuts+", "AeTuts+"]

The above code first plucks (extracts) the names from the Tuts array of objects. It then pass the resulted array onto the map function, which then append the plus sign to each element of the array. With the map function, the value can remain unchanged, or it can be mutated in any way you desire.

_.map(list, iteratee, [context])

Produces a new array of values by mapping each value in list through a transformation function (iteratee). If list is a JavaScript object, iteratee's arguments will be (value, key, 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]

What is the purpose of the all method?

The all method is useful if you need to check to see if all values in a collection match a certain criteria:

var Scores = [95, 82, 98, 78, 65];
var hasPassed = _(Scores).all(function (value){return value>50; });

console.log(hasPassed);
// true

What is the purpose of the uniq method?

This method removes all duplicate elements from the array and provide you with only unique elements:

var uniqTest = _.uniq([1,5,4,4,5,2,1,1,3,2,2,3,4,1]);

console.log(uniqTest);
// [1, 5, 4, 2, 3]

Only the first instance is included in the result, and the original order is kept.

Produces a duplicate-free version of the array, using === to test object equality. If you know in advance that the array is sorted, passing true for isSorted will run a much faster algorithm. If you want to compute unique items based on a transformation, pass an iteratee function.

_.uniq(array, [isSorted], [iteratee]);

_.uniq([1, 2, 1, 3, 1, 4]);
=> [1, 2, 3, 4]

What is the purpose of the range method?

The range method lets you create a 'range' or list of number:

var tens = _.range(0, 100, 10);

console.log(tens);
// [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]

The parameters are: the starting value, the ending value, and the step value.

What is the purpose of the intersection method?

The intersection method compares two or more arrays to each other and returns the list of elements that are found in all of the passed arrays:

var tens = _.range(0, 100, 10);
var eights = _.range(0, 100, 8);
var fives = _.range(0, 100, 5);

var common = _.intersection(tens, eights, fives );
console.log(common);
// [0, 40, 80]

Does _ provide any methods for object oriented programming?

Yes. It provides various methods to clone and extend objects.

How can we use _ to extract a list of keys or values from an object?

var Tuts = { 
    NetTuts : 'Web Development',  
    WPTuts : 'WordPress',  
    PSDTuts : 'PhotoShop', 
    AeTuts : 'After Effects'
};
var keys = _.keys(Tuts);
var values = _.values(Tuts);

console.log(keys);
console.log(values);
// NetTuts,WPTuts,PSDTuts,AeTuts
// Web Development,WordPress,PhotoShop,After Effects

What is the purpose of the defaults method?

The defaults method creates an object with sensible default value when one might not have been used when creating the object:

var tuts = { NetTuts : 'Web Development'};
var defaults = { NetTuts : 'Web Development', niche: 'Education'};

_.defaults(tuts, defaults);

console.log(tuts);
// Object { NetTuts="Web Development", niche="Education"}

In other words, the defaults method takes two parameters. The first parameter is the original object, and the second parameter is an object containing default values. It merges the default properties and values from the default object into the original object if the original object does not have that property and value.

What is the purpose of the bind function?

The bind function binds a function to an object, and it returns a new function.

var o = { greeting: "Howdy" };
var f = function(name) { return this.greeting +" "+ name; };
var greet = _.bind(f, o);

greet("Jess");

The bind function lets you keep the value of this whenever and wherever the function is called. In the above code, the bind function takes two parameters. The first parameter is a function, and the second parameter is an object. It binds the function to the object, and returns a new function. We are not supposed to use the original function directly. We are supposed to use the resulted function (greet), and whenever we invoke the resulted function (greet), the original function is invoked, and inside the original function, the this keyword points to the original object.

How to use the template functionality provided by _ ?

var data =   {site: 'NetTuts'};
var template =   'Welcome! You are at <%= site %>';

var parsedTemplate = _.template(template,  data );

console.log(parsedTemplate); 
// Welcome! You are at NetTuts

By default, _ uses ERB style tokens. However, this is customizable.

What is the purpose of the each method?

_.each(list, iteratee, [context])

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.

Can we break out of the loop if we use the each method?

No. It's also good to note that an each loop cannot be broken out of. If we need to break out of the loop, consider using _.find instead of _.each.

What is the purpose of the reduce method?

_.reduce(list, iteratee, [memo], [context])

Also known as inject and foldl, reduce boils down a list of values into a single value. Memo is the initial state of the reduction, and each successive step of it should be returned by iteratee. The iteratee is passed four arguments: the memo, then the value and index (or key) of the iteration, and finally a reference to the entire list. If no memo is passed to the initial invocation of reduce, the iteratee is not invoked on the first element of the list. The first element is instead passed as the memo in the invocation of the iteratee on the next element in the list.

var sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0);
=> 6

What is the purpose of the reduceRight method?

_.reduceRight(list, iteratee, memo, [context])

The right-associative version of reduce. Delegates to the JavaScript 1.8 version of reduceRight, if it exists. Foldr is not as useful in JavaScript as it would be in a language with lazy evaluation.

var list = [[0, 1], [2, 3], [4, 5]];
var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
=> [4, 5, 2, 3, 0, 1]

What is the purpose of the find method?

_.find(list, predicate, [context])

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

What does the find function alias for?

detect

What is the purpose of the filter method?

_.filter(list, predicate, [context])

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]

What does the filter method alias for?

select

What is the purpose of the where function?

_.where(list, properties)

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: "Shakespeare", year: 1611});
=> [{title: "Cymbeline", author: "Shakespeare", year: 1611},
    {title: "The Tempest", author: "Shakespeare", year: 1611}]

What is the purpose of the findWhere function?

_.findWhere(list, properties)

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"});

What is the purpose of the reject method?

_.reject(list, predicate, [context])

Returns the values in list without the elements that the truth test (predicate) passes. The opposite of filter.

var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> [1, 3, 5]

What is the reject method opposite of?

The reject method is the opposite of the filter method.

What is the purpose of the every method?

_.every(list, [predicate], [context])

Returns true if all of the values in the list pass the predicate truth test. Alias for the all method.

What is the purpose of the some method?

_.some(list, [predicate], [context])

Returns true if any of the values in the list pass the predicate truth test. Short-circuits and stops traversing the list if a true element is found.

What does the some method alias for?

The some method is an alias for the any method.

What is the purpose of the contains method?

_.contains(list, value)

Returns true if the value is present in the list. Uses indexOf internally, if list is an Array.

_.contains([1, 2, 3], 3);
=> true

What is the purpose of the invoke method?

_.invoke(list, methodName, *arguments)

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]]

What is the purpose of the max method?

_.max(list, [iteratee], [context])

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.

var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}];
_.max(stooges, function(stooge){ return stooge.age; });
=> {name: 'curly', age: 60};

What is the purpose of the min method?

_.min(list, [iteratee], [context])

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.

var numbers = [10, 5, 100, 2, 1000];
_.min(numbers);
=> 2

What is the purpose of the sortBy method?

_.sortBy(list, iteratee, [context])

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]

What is the purpose of the groupBy method?

_.groupBy(list, iteratee, [context])

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"]}

What is the purpose of the indexBy method?

_.indexBy(list, iteratee, [context])

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}
}

What is the purpose of the countBy method?

_.countBy(list, iteratee, [context])

Sorts a list into groups and returns a count for the number of objects in each group. Similar to groupBy, but instead of returning a list of values, returns a count for the number of values in that group.

_.countBy([1, 2, 3, 4, 5], function(num) {
  return num % 2 == 0 ? 'even': 'odd';
});
=> {odd: 3, even: 2}

What is the purpose of the shuffle method?

_.shuffle(list)

Returns a shuffled copy of the list, using a version of the Fisher-Yates shuffle.

_.shuffle([1, 2, 3, 4, 5, 6]);
=> [4, 1, 6, 3, 5, 2]

What is the purpose of the sample method?

_.sample(list, [n])

Produce a random sample from the list. Pass a number to return n random elements from the list. Otherwise a single random item will be returned.

_.sample([1, 2, 3, 4, 5, 6]);
=> 4

_.sample([1, 2, 3, 4, 5, 6], 3);
=> [1, 6, 2]

What is the purpose of the toArray method?

_.toArray(list)

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]

What is the purpose of size method?

_.size(list)

Return the number of values in the list.

_.size({one: 1, two: 2, three: 3});
=> 3

What is the purpose of the partition method?

_.partition(array, predicate)

Split array into two arrays: one whose elements all satisfy predicate and one whose elements all do not satisfy predicate.

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

Are _ functions designed to work with sparse array?

No. All array functions will also work on the arguments object. However, Underscore functions are not designed to work on "sparse" arrays.

What is the purpose of the first method?

_.first(array, [n])

Returns the first element of an array. Passing n will return the first n elements of the array.

_.first([5, 4, 3, 2, 1]);
=> 5

What is the purpose of the initial method?

_.initial(array, [n])

Returns everything but the last entry of the array. Especially useful on the arguments object. Pass n to exclude the last n elements from the result.

_.initial([5, 4, 3, 2, 1]);
=> [5, 4, 3, 2]

What is the purpose of the last method?

_.last(array, [n])

Returns the last element of an array. Passing n will return the last n elements of the array.

_.last([5, 4, 3, 2, 1]);
=> 1

What is the purpose of the rest method?

_.rest(array, [index])

Returns the rest of the elements in an array. Pass an index to return the values of the array from that index onward.

_.rest([5, 4, 3, 2, 1]);
=> [4, 3, 2, 1]

What does the rest method alias for?

tail and drop

What is the purpose of the compact method?

_.compact(array)

Returns a copy of the array with all falsy values removed. In JavaScript, false, null, 0, "", undefined and NaN are all falsy.

_.compact([0, 1, false, 2, '', 3]);
=> [1, 2, 3]

What is the purpose of the flatten method?

Flattens a nested array (the nesting can be to any depth). If you pass shallow, the array will only be flattened a single level.

_.flatten(array, [shallow]);

_.flatten([1, [2], [3, [[4]]]]);
=> [1, 2, 3, 4];

_.flatten([1, [2], [3, [[4]]]], true);
=> [1, 2, 3, [[4]]];

What is the purpose of the without method?

Returns a copy of the array with all instances of the values removed.

_.without(array, *values);

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

What is the purpose of the union method?

Computes the union of the passed-in arrays: the list of unique items, in order, that are present in one or more of the arrays.

_.union(*arrays);

_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2, 3, 101, 10]

What is the purpose of the intersection method?

Computes the list of values that are the intersection of all the arrays. Each value in the result is present in each of the arrays.

_.intersection(*arrays);

_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2]

What is the purpose of the difference method?

Similar to without, but returns the values from array that are not present in the other arrays.

_.difference(array, *others);

_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
=> [1, 3, 4]
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License