Sunday, 13 October 2013

Linq.js - where to filter on sub collections

Linq.js (you can find more info on CodePlex - http://linqjs.codeplex.com) provides convenient way manipulating your javascript collections (mainly arrays) and exposes it as LINQ that we are familiar with in .NET world.

One issue I found that it is hard to find information on how to achieve it is that when I want to apply the where clause on sub collections.

For example, given the following array:

var cars = [
  {id: "F001", make: "Ford", model: "Fiesta", 
    colors: [
      {id: 1, name: "Red"},
      {id: 2, name: "Blue"}
    ]
  },
  {id: "T001", make: "Toyota", model: "Corolla",
    colors: [
      {id: 1, name: "Red"},
      {id: 3, name: "Silver"}
    ]
  },
  {id: "T002", make: "Toyota", model: "Yaris",
    colors: [
      {id: 1, name: "Red"},
      {id: 3, name: "Silver"},
      {id: 4, name: "White"}
    ]
  }
];

It is pretty easy to find cars that are made by Toyota (note that the code examples below are using linq.js 3.x:


var toyotaCars = Enumerable.from(cars)
                           .where("c=> c.make == 'Toyota'");

And we will get Corolla and Yaris.

However, when I want to find cars that are available in blue and how do I suppose to do that?

People might have tried the following already:


var blueCars = Enumerable.from(cars)
                         .where("c=> c.colors.name == 'Blue'");

Or

    .where(function(c) {return (c.colors.name == 'Blue');})


Unfortunately this is not how it works and you will get nothing. Obviously linq.js is trying to work as close as to .NET LINQ but nothing is perfect. So to achieve what we want is the following:


var blueCars = Enumerable.from(cars)
    .where(function(o) {
      return (Enumerable.from(o.colors)
                        .where("c => c.name == 'Blue'").any());
    });

Here you go, we will get Ford Fiesta!

No comments:

Post a Comment