Single Page App – Finding Items in JSON Using Underscore or LoDash

Underscore.jsUnderscore is a utility-belt library for JavaScript that provides a lot of the functions and programming support that you would expect in Prototype.js (or Ruby), but without extending any of the built-in JavaScript objects.

Underscore provides 80-odd functions that help you deal with collections, arrays, functions, objects, and more.

You will want Underscore for you non-DOM code or even complex front end code, such as MVC. You can use map, select, invoke or specialized helpers: function binding, JavaScript templating, deep equality testing. Underscore uses built-in functions in modern browsers when you want to use forEach, map, reduce, filter, every, some and indexOf.

Underscore gives you simple templating, too, similar to what you learned about in Object JavaScript – External Templates Using Mustache, jQuery.

You can use Underscore in your Web application or on Node.js.

When minified and GZipped it weighs in at less than 4Kb. Where possible it delegates functionality to native browser implementations for performance. It has no other dependencies and so adds very little overhead to your total script assets. It can be used on the client or server.

In this post, you’ll learn how to use Underscore for finding items in your single page app. You’ll learn how to:

  • Select a group of toys based on price cutoff.
  • Find a toy from its name.
  • Get a sorted list of unique categories.
  • Sort the list of product names.

In a later post, you’ll learn how to create a list of search terms and respond to a search request using JavaScript and Underscore.

There is a lot more available in Underscore. For another good tutorial, see Getting Cozy With Underscore.js.

Getting Underscore

You can get Underscore on GitHub.

For your Visual Studio projects you can get Underscore from NuGet:

  • underscore.js. JavaScripts functional programming helper library.
  • UnderscoreKO. Adds all the useful collection and array methods from Underscore.js to Knockout observable arrays. Also includes several convenience methods to manipulate the underlying array.

Next you include Underscore in your application. Underscore is not tightly bound to the DOM, doesn’t make any assumptions about other libraries or frameworks that may be in use and doesn’t require any setup or configuration; you simply include the library file in your page and you can start calling its methods.

Then just like in $ can be used as the jQuery global, you can use the underscore _ to access the Underscore methods.

Data for This Tutorial

For this tutorial, you can use sample product data that is saved in a Data/products.txt file. Here’s the data that you can load using jQuery getJSON. Note, that Underscore does not require jQuery. You are just using it to load the data from products.txt.

Select Items in an Array

There are a couple ways you can call Underscore methods. You can use the functional approach, where you call the method directly on the _ object.

Let’s take an example where you want to select the scores over 90:

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

  topScorers = [],
  scoreLimit = 90; topScorers = _.select(scores, function(score){
return score > scoreLimit;
}); console.log(topScorers);

Or you can use the object oriented approach where you call the underscore method on the object you want to manipulate.

var scores = [84, 99, 91, 65, 87, 55, 72, 68, 95, 42], 
  topScorers = [], 
  scoreLimit = 90;
 
topScorers = _(scores).select(function(score){ 

  return score > scoreLimit; }); console.log(topScorers);

In this second way, you can also chain more functions to the result.

Product Select

In your product data, you can select the items that cost more than 40.

$.getJSON('Data/products.txt', function (data) {
   var products = data.products;
   console.log("products: " + JSON.stringify(products));

   var expensiveProducts = _.select(products, function (product) {
    // underscore walks through each product for the comparison
    console.log("product " + JSON.stringify(product));
    return product.price > 40;
  });   console.log("expensiveProducts: " + JSON.stringify(expensiveProducts)); });

Find an Item

_.find() looks through each value in the list, returning the first one that passes a test. It returns undefined if no value passes the test. The function returns as soon as it finds the first time that passes the test.

var doll = _.find(products, function (product) {
   // underscore walks through each product and returns
   // the first one found. 
   return product.name === "Doll";
});

Pluck From a Unique List

You can use _.uniq to parse an array and removes duplicate elements.  You end up with an array with only unique elements.

For example,

_.uniq([1, 2, 1, 3, 1, 4]);
// returns an array: [1, 2, 3, 4]

First comparison object with unique return value used as unique.

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 your own values, pass an iterator function. The iterator function return value is used for comparison.

In our case, we have an unsorted list and want to get the categories. So we can return the product.category field in our iterator to be used by Underscore for the unique comparisons.

var unique = _.uniq(products, false, function (product) {

  // underscore walks through each product
  return product.category; });

 

But this returns an array of products where the first unique category is found. It is not a list of categories. You can  _.pluck() a single field from the products. Tell pluck which of the fields to return in a new array.

var categories = _.pluck(unique, 'category');

 

I get back the list of categories:

categories: ["Toy","Grocery"]

Sort

_.sortBy returns a list, ranked in ascending order by the results that you provide in your iterator. In the case of sorting our products, you can also pass in the string name of the property to sort by.

var sortedProducts = _.sortBy(products, 'name');

Or if we wanted to sort by the price sorted lowest price product to highest price.

var priceSort = _.sortBy(products, 'price') ;

You can then reverse the array if you want the highest to lowest price.

var priceReverseSort = _.sortBy(products, 'price').reverse();

More Than Underscore

imageBefore writing a general purpose function to deal with objects, arrays, be sure to check out Underscore or Lo-Dash.

Lo-Dash is similar in many ways to Underscore. It uses the _ global.

You can get it from lodash on GitHub. And for Visual Studio projects it is available from  Lo-Dash on NuGet.

Lo-Dash provides a more consistent cross-environment iteration support for arrays, strings, objects, and arguments objects. It has become a superset of Underscore, providing more consistent API behavior, more features (like AMD support, deep clone, and deep merge), more thorough documentation and unit tests (tests which run in Node, Ringo, Rhino, Narwhal, PhantomJS, and browsers), better overall performance and optimizations for large arrays/object iteration, and more flexibility with custom builds and template pre-compilation utilities.

Here are links to the Lodash functions:

Arrays

Chaining

Collections

Functions

Objects

Utilities

References

Lo-Dash

Advertisements

One comment

  1. Pingback: Single Page App – Using RequireJS Asynchronous Module Definition (AMD) Modules with jQuery, LoDash | DevDays®