Need LINQ but Writing JavaScript?

sketchArchOne of the tasks that I found cumbersome when writing JavaScript is simple collection manipulation. I have gotten spoiled in C# with LINQ. Sorting, filtering, shaping and more is easy with LINQ but what about in JavaScript? Underscore.js to the rescue.

Underscore.js is a small utility library that can help in collection manipulation (as well as other great features). I first started using Underscore.js to replace jQuery's (and AngularJS's) for-each implementations. I find underscore's simple and quick. Like much of JavaScript, the magic is happening in a callback function (think Lambda):


var a = [1, 2, 3, 4, 5];

_.each(a, function (i) {
    console.log("each: " + i);
    // Break out of loop by returning false
    if (i > 3) return false; // doesn't work 

Note that the "_" is an aliased object that exposes most of the Underscore.js behavor (e.g. functions). So _.each is a function on the underscore object (e.g. "_").

That works great, but I can't break out of it like I can in jQuery…so Underscore.js' _.every function to the rescue:


var a = [1, 2, 3, 4, 5];

// Faking out the behavior
_.every(a, function (i) {
    // Break out of loop by returning false
    if (i > 3) return false; // works 
    console.log("every: " + i);
    return true; // Continues the every


But that's just the tip of the iceberg of goodness. When you're dealing with a more nuanced collection (e.g. like one from an API call, you may want to manipulate it in memory. Here's the data we're starting from:


var data = [{
    name: "Freddy Freeman",
    position: "1B",
    team: "ATL",
    stats: {
        avg: .310,
        hr: 13,
        r: 63,
        rbi: 76
}, {
    name: "Chris Johnson",
    position: "3B",
    team: "ATL",
    stats: {
        avg: .337,
        hr: 8,
        r: 43,
        rbi: 45
}, {
    name: "Brian McCann",
    position: "C",
    team: "ATL",
    stats: {
        avg: .277,
        hr: 17,
        r: 31,
        rbi: 45
}, {
    name: "Andrelton Simmons",
    position: "SS",
    team: "ATL",
    stats: {
        avg: .245,
        hr: 11,
        r: 60,
        rbi: 40
}, {
    name: "Jason Heyward",
    position: "RF",
    team: "ATL",
    stats: {
        avg: .238,
        hr: 10,
        r: 52,
        rbi: 32
}, ];


This is simple data but we'd like to be able to perform some set operations like sorting, filters and others. Let's start with sorting. To sort, we simply call _.sortBy which takes a collection (anything iterable) and a callback that accepts each item in the collection like so:


var sorted = _.sortBy(data, function (i) { return; });

In this example our collection (the data object) is passed in as the first parameter and the callback function is the second parameter. We're returning the name property because that's what we want to sort by.  Look familiar? It should.

How about filtering?

var filtered = _.filter(data, function (i) { return i.stats.avg > .300; });


In this example, we're filtering by returning a Boolean value on whether to include the item in the filtered results.

Underscore.js includes other really useful items like map, reduce, find, contains, min, max and others. It really enables many of the scenarios that I'd use LINQ in C# (or VB.NET).  But these examples so far show only a single operation. What about when you want to perform a series of operations (which is often the norm)?  _.chain to the rescue:

var chained = _.chain(data)
    .filter(function (i) { return i.stats.avg < .300; })
    .sortBy(function (i) { return; })


_.chain allows you to specify a collection (e.g. data) and then call multiple operations on that collection. You must end the set of operations to a call to .value to complete the chain of operations. By using chain, you can perform a series of operations and easily do LINQ-like functionality. You can get Underscore.js here (and the docs including a great annotated source):

If you want to play with it, I have a JSFiddle here with the code I've been discussing:


What do you think?

Shawn Wildermuth
Author, Teacher, and Coach

My Courses

Building a Web App with ASP.NET Core, MVC6, EF Core, Bootstrap and Angular (updated for 2.0)
Using Visual Studio Code for ASP.NET Core Projects (new)
Implementing and Securing an API with ASP.NET Core
Building a Web App with ASP.NET Core, MVC6, EF Core and AngularJS
Building a Web App with ASP.NET5, MVC6, EF7, and AngularJS (Retired)
Best Practices in ASP.NET: Entities, Validation, and View Models
Webstorm Fundamentals
Front-End Web Development Quick Start
Lessons from Real World .NET Code Reviews
Node.js for .NET Developers

Application Name WilderBlog Environment Name Production
Application Ver Runtime Framework .NETCoreApp,Version=v2.0
App Path D:\home\site\wwwroot\ Runtime Version .NET Core 4.6.26020.03
Operating System Microsoft Windows 10.0.14393 Runtime Arch X86