Home » Underscore » Underscore Collections

Underscore Collections

Welcome to the first module of Undersore.js tutorial. In this Module we will cover some basic concepts of underscore collections, how collections can be used to manipulate JavaScript arrays and objects, how the user can use collections to reduce the application development effort. As we move, we will learn about each of the collection that underscore provides.

So let’s go through each collection one by one.

To demonstrate collection i will be using two arrays throughout this module.

var numberArray = [1,2,3,4,5,6,7,8,9]; // integer array
var objectArray = [{name:"Himanshu", age: 26},{name:"John", age: 23}, {name:"Sarah", age: 28}, {name:"Steve", age:33},{name:'Bosco', age:26},{name:'Piyush', age:28}]; // object array

 

_.each(list, iterator, [context])
_.each() function is same as for loop in JavaScript. The main advantage of this function is it helps to write cleaner and lesser number of lines of code.
This function iterates over each item in the list and return the result. Iterator function is passed as a second argument and iterate over each value in the list.
Optionally we can pass the context parameter.

_.each(objectArray,function(e){
   console.log(e.name);
});

// console: Himanshu, John, Sarah, Steve, Bosco, Piyush

Here we are passing objectArray as a list; iterator function will iterate over each item and will print the name property.

 

_.map(list, iterator, [context])
_.map() function iterates over each value in an array and returns new array, with iterated values.

var people = _.map(objectArray, function(e){
   return e.name+ " is "+ e.age + " years old.";
});
console.log(people);

//console: ["Himanshu is 26 years old.","John is 23 years old." ...]

Here we are passing an array object and applying iterator function on each object. Iterator function will take name and age property of an object and will create a new string and add it to new array.
The result will be a new string array with mapped values. 

Below is another example of _.map() function which will add each of the item in an array and will return new array with updated values.

var sum = _.map(numberArray, function(e){
   return e+e;
});
console.log(sum);

// console: [2, 4, 6, 8, 10, 12, 14, 16, 18]

 

_.reduce(list, iterator, memo, [context])
_.reduce() function returns a single value by memorizing (or caching) the previous result.
We need to pass context if we are working with an object array.

var ageSum = _.reduce(objectArray, function(memo, people){
   return memo + people.age;
},0);
console.log(ageSum);

// console: 164

In above example we are adding age property of each object from ObjectArray. Here you will notice we are passing 0 (zero) as a memo, it is because we are working with object array and not with an integer array. Adding 0 will do 0+26 in first step and so on. If we pass 1 then the first step would be 1+26.

var sum = _.reduce(numberArray, function(memo, number){
   return memo + number;
});
console.log(sum);

// console: 45

 

_.find(list, iterator, [context])
_.find() function finds and returns the first value that matches the iteration criteria. If no element matches the iteration criteria then it returns undefined.

find() function checks the list till the first value that matches the criteria and doesn’t check the remaining items in the list.

var findPerson = _.find(objectArray, function(e){
   return e.age == 33;
});
console.log(findPerson);

// console: {name: "Steve", age: 33}

In above example find function will check list till {name:”Steve”, age:33} and will return.

var findNumber = _.find(numberArray, function(e){
   return (e%2) == 0;
});
console.log(findNumber);

// console: 2

 

_.filter(list, iterator, [context])
_.filter() function is same as find, except it iterates over each item in the list and returns all the items that matches the iteration criteria.

var mulitpleOfTwo = _.filter(numberArray, function(e){
   return (e%2) == 0;
});
console.log(mulitpleOfTwo);

//console: 2, 4, 6, 8

var peopleBelowThirty = _.filter(objectArray, function(e){
   return e.age < 30;
});
console.log(peopleBelowThirty);

//console: This will return new array with all the items except "Steve", because "Steve" has age < 30

 

_.where(list, properties)
Whereas _.filter() function returns all the items that match iterator criteria, _.where() function returns all the items that match property criteria that we pass in properties argument.
If nothing matches then it returns blank value.

var peopleBelowThirty = _.where(objectArray, {age:26});
console.log(peopleBelowThirty);

// console: {name:'Himanshu',age:26}, {name:'Bosco', age:26}

We can pass single as well as multiple properties (separated by comma)
Only those objects will be returned which match all the properties. i.e. in above example if i pass

{name:'Himanshu',age:26}

then result would be

// console: {name:'Himanshu',age:26}

 

_.findWhere(list, properties)
_.findWhere() is the combination of _.find() and _.where() function, _.findWhere() function returns the first value that matches the property criteria.
Undefined will be returned if nothing is found.

var peopleArray = _.findWhere(objectArray, {age: 26});
console.log(peopleArray);

// console: name: "Himanshu", age: 26

 

_.reject(list, iterator, [context])
_.reject() function is the opposite of filter. It rejects those items that match the iteration criteria and return the remaining items. _.reject() function is used when you want to remove some unused values, for example if you want to apply some logic on those employees who have age more than 30, in this case you can reject the employees who have age less then 30 and apply the logic on remaining employees.

var peopleAboveThirth = _.reject(objectArray, function(e){
   return e.age <30;
});
console.log(peopleAboveThirth);

//console: {name:"Steve", age:33}

In above example all the items which are below age 30 will be rejected.

var oddNumber = _.reject(numberArray,function(e){
   return (e%2)==0;
});
console.log(oddNumber);

// console: [1, 3, 5, 7, 9]

Here all the integers that are divisible by 2 will be rejected.

 

_.every(list, [iterator], [context])
_.every() function returns true if all the items within an array passes the iterator criteria.
It uses JavaScript’s way to determine truth and false.
i.e. for example if we have true == 1; JS will return true (JS automatically does necessary type conversions), whereas true === 1 will return false because true is a string and 1 is an integer (=== does not do any type conversion)

var areDivisibleByTwo = _.every(numberArray, function(e){
   return (e%2) == 0;
});
console.log(areDivisibleByTwo);

// console: false

It will return false because all the items in array are not divisible by 2.

var arePeopleAboveThirty = _.every(objectArray, function(e){
   return e.age < 30;
});
console.log(arePeopleAboveThirty);

// console: false

This will also return false because Steve’s age is greater than 30, if we change the condition like (e.age <40) then it will return true because all the items have age value below 40.

 

_.some(list, [iterator], [context])
_.some() function returns true if any of the items within an array passes the iterator criteria.
It breaks the loop if any of the item returns true.

var divisibleByTwo = _.some(numberArray, function(e){
   return (e%2) == 0;
});
console.log(divisibleByTwo);

// console: true

This will return true because few of the items are completely divisible by 2.

var arePeopleAboveThirty = _.some(objectArray, function(e){
  return e.age > 30;
});
console.log(arePeopleAboveThirty);

// console: true

The important point here is, _.some() function will check till “{name:”Steve”, age: 33}” and skip other items because age (33) is greater than 30, hence it will return true and break the loop.

 

_.contains(list, value)
_.contains() function return true if the list contains given value, or else return false.
_.contain function will check type as well as value of second parameter.

var divisibleByTwo = _.contains(numberArray, 2);
console.log(divisibleByTwo);

// console: true

This will return true because numberArray has 2, if we pass 2 as a string instead of integer it will return false.

To apply the _.contain function on object array, first fetch the object and then apply _.contain.

var divisibleByTwo = _.contains(objectArray, 'Himanshu');
console.log(divisibleByTwo);

// console: false

It will return false because we are applying this on complete object array and not on an object.

If we pass

_.contains(objectArray[0], 'Himanshu');

Then it will return true because objectArray[0] will return an object, which has given value in it.

 

_.invoke(list, methodName, [*arguments])
The Purpose of _.invoke() function is to call methodName on each value in the list and return new list. for example, if you have multiple arrays and you want to sort all the arrays at once than you can use _.invoke().
Additionally we can pass parameters in [*arguments]

var shuffledArray = [[5,3,4,1,2],['Himanshu','John','Sarah','Steve','Bosco']];
console.log(_.invoke(shuffledArray,'sort'));

// console: [1,2,3,4,5] , [Bosco,Himanshu,John,Sarah,Steve]

We are passing “sort” as a function that will be applied on each list. So we are getting both the array in sorted order.

console.log(_.invoke(shuffledArray,'join','*'));

// console: ["5*3*4*1*2", "Himanshu*John*Sarah*Steve*Bosco"]

In above example we are passing join as a function and * as an argument. Resulted list will have each item separated by *

 

_.pluck(list, propertyName)
_.pluck() function is used to pluck the values of a given propertyName from a list. for example, if you want to find out the average of particular student then you can simply pluck marks of each subject and find out the average of that student by adding all the marks and then divide the sum by number of subjects.

var retrieveName = _.pluck(objectArray, 'name');
console.log(retrieveName);

// console: "Himanshu", "John", "Sarah", "Steve", "Bosco", "Piyush"

This function is useful when we want to retrieve any property value and apply some logic on that.

 

_.max(list, [iterator], [context]) / _.min(list, [iterator], [context])
Return the max/min value in an array.

var number = _.min(numberArray);
console.log(number);

// console: 1

var Person = _.max(objectArray, function(e){
return e.age;
});
console.log(Person);

// console: name: "Steve", age: 33 // return an object with max age

 

_.sortBy(list, iterator, [context])
_.sort() function will return a sorted array in ascending order.
Advantage of this function is we can provide our own sorting criteria.

var sortNumber = _.sortBy([1,5,3,4,5,3,1,5,6,7,9,8], function(e){
   return Math.sin(e);
});
console.log(sortNumber);

// console: 5, 5, 5, 4, 6, 3, 3, 9, 7, 1, 1, 8

var sortAge = _.sortBy(objectArray, function(e){
   return e.age;
});

console.log(sortAge);
// console: This will sort an array according to given age in ascending order.

 

_.groupBy(list, iterator, [context])
_.group() function iterates over a list; and groups the values according to iterator. This can be little bit confusing without an example, so lets create an example to demonstrate groupBy.

var groupNumber = _.groupBy(numberArray, function(e){
   return e%2== 0;
});
console.log(groupNumber);

// console: this will return two arrays, true (even number) and false (odd number)

If you run above example and see the console you will get two arrays true and false; true array will have those values which passes iterator function criteria(2,4,6,8) and false array will have failed values. (1,3,5,7,9)

var ageGroup = _.groupBy(objectArray, function(e){
   return Math.round(e.age);
});
console.log(ageGroup);

// console: this will return four arrays, for 23,26,28,33

 

_.indexBy(list, iterator, [context])
_.indexBy() function is same as _.groupBy(), but instead of returning values iterator function returns key which is used to group the values
It returns an object in sorted order.

var indexByNumber = _.indexBy(numberArray, function(e){
   return e;
});
console.log(indexByNumber);

//console: {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}
var indexByName = _.indexBy(objectArray, 'name');
console.log(indexByName);
// console: Object {Himanshu: Object, John: Object, Sarah: Object, Steve: Object, Bosco: Object…}

In console you will get “name” property as a key, because we passed ‘name’. Another point to notice here is we are getting an object in “alphabetically”sorted order.

 

_.countBy(list, iterator, [context])
_.countBy() function is same as _.groupBy() and _.indexBy() function but instead of returning group or keys this function returns count of objects in each group.

var countByNumber = _.countBy(numberArray,function(e){
   return e;
});
console.log(countByNumber);

// console: {1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1, 8: 1, 9: 1}

Each group has only one element in it so above code is returning 1 (count).

var countByAge = _.countBy(objectArray, function(e){
   return e.age;
});
console.log(countByAge);

// console: 23: 1, 26: 2, 28: 2, 33: 1

Here “Himanshu” and “Bosco” have age 26 so it is returning count as 2 for 2nd group and so on.

 

_.shuffle(list)
_.shuffle() function shuffles the list. This function uses Fisher-Yates shuffle algo to shuffle list values.

var suffleNumbers = _.shuffle(numberArray);
console.log(suffleNumbers);

// console : 8, 9, 5, 3, 6, 1, 2, 7, 4

var sufflePeople = _.shuffle(objectArray);
console.log(sufflePeople);

// console: return array of shuffled objects

 

_.sample(list, [n])
_.sample() function produces a random set of sample values.
[n] is number of sample value(s) we want. Only one value will be returned if nothing is passed in n.

var sampleNumbers = _.sample(numberArray, 5);
console.log(sampleNumbers);

// console: 1, 8, 2, 5, 9

We have passed 5 as a second parameter of _.sample() function so it is returning 5 random values. If we won’t pass anything then it will return only one random value.

var samplePeople = _.sample(objectArray, 3);
console.log(samplePeople);

// console: return array of 3 objects

 

_.size(list)
_.size() function returns size of list.

var numberArraySize = _.size(numberArray);
console.log(numberArraySize);

// console: 9

var objectArraySize = _.size(objectArray);
console.log(objectArraySize);

// console: 6

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>