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!

2 comments:

  1. Hello, thanks for this toot, but how about i only get the specific value from parent array
    ex. i want to get all the blue
    expected output is :
    var cars = [
    {id: "F001", make: "Ford", model: "Fiesta",
    colors: [
    {id: 2, name: "Blue"}
    ]
    },
    {id: "T002", make: "Toyota", model: "Yaris",
    colors: [
    {id: 4, name: "Blue"}
    ]
    }
    ];

    i tried the above code but the output is this
    var cars = [
    {id: "F001", make: "Ford", model: "Fiesta",
    colors: [
    {id: 1, name: "Red"},
    {id: 2, name: "Blue"}
    ]
    },
    {id: "T002", make: "Toyota", model: "Yaris",
    colors: [
    {id: 1, name: "Red"},
    {id: 3, name: "Silver"},
    {id: 4, name: "Blue"}
    ]
    }
    ];

    thanks

    ReplyDelete
  2. Hello, wow it's been a while!

    Could you try the following:

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

    ReplyDelete