LINQ to JavaScript

I’ve been using LINQ in C# since shortly after Visual Studio 2008 was released. It was an awesome addition to the language, allowing you to call into a database model in a method that is identical to how you deal with in-memory collections. Admittedly, LINQ is basically an entire data-munging framework built around various classic functional programming constructs such as map and reduce.

If LINQ has a problem, it’s that writing a new provider can be really difficult, since it requires pretty deep understanding of .NET expression trees, however most people won’t ever need to do that. Plus, LINQ is one of the primary reasons why extension methods were added to .NET, and even if LINQ wasn’t as great as it is, extension methods are something to get excited about in a statically-typed language.

Anyway, for manipulating pure data, LINQ is a wonderful too, and Chris Pietschmann has released a version of LINQ for JavaScript. And it’s in the flexible Microsoft Reciprocal License, so it’s easy to download and use. It’s about 7k raw, with very clean code, and about .7k after minification and gzip, for a minimal impact on page weight. And, if you’ve ever written LINQ, the syntax is basically identical to the lambda syntax.

var myList = [
  {FirstName:"Chris",LastName:"Pearson"},
  {FirstName:"Kate",LastName:"Johnson"},
  {FirstName:"Josh",LastName:"Sutherland"},
  {FirstName:"John",LastName:"Ronald"},
  {FirstName:"Steve",LastName:"Pinkerton"}
];
var exampleArray = 
        JSLINQ(myList)
        .Where(function(item){ return item.FirstName.match(/^Jo/); })
      .OrderBy(function(item) { return item.FirstName; })
      .Select(function(item){ return item.FirstName; });

/**
 * exampleArray = [ "John", "Josh" ]
 **/

Now, the blurb that Chris wrote for JSLINQ is a bit wrong. He says the following:

LINQ to JavaScript (JSLINQ for short) is an implementation of LINQ to Objects implemented in JavaScript. It is built using a set of extension methods built on top of the JavaScript Array object. If you are using an Array, you can use JSLINQ.

The important distinction is that JSLINQ works on array-like objects, such as HTMLCollections. But, also that I first red the ‘extension methods’ comment to mean that he was modifying Array.prototype. Thankfully, that’s not the case, which is why you need to call JSLINQ on your collection first.

Personally, I think the ability to query the DOM with this is less useful than the ability to query over data sets, especially since YUI3 already provides pretty rich support (using CSS Selectors built into modern browsers). However, the ability to take an existing list and filter it down using LINQ style expressions can be very useful. YUI3’s NodeList is not an array-like object. There are basically two options.

The following example will get all the anchor tags on a given page which reference internal links (links to the same domain as the page):

JSLINQ(Y.NodeList.getDOMNodes(Y.all('a')))
    .Where(function(item){ return item.href.match(location.host); }
    .Select(funtion(item) { return item; }

Y.all('a[href*=' + location.host + ']');

The second example does require the ‘selector-css3’ submodule to be loaded (it isn’t by default), but it’s a far cleaner syntax for querying the DOM, so the examples of JSLINQ that query the DOM aren’t necessarily the most useful, but if you need to do any client-side filtering or munging of data, LINQ is a really nice syntax for doing that, which is SQL-like, but still unique to your environment. If you’re already familiar with .NET 3.5 and LINQ in that world, then I’d suggest looking at JSLINQ for your projects, it’s familiar, and it looks as though it should work well.