Tuesday, July 15, 2014

Group by in C# and linq.js

Being a C# developer I really like and use Linq a lot. It can simplify code a great deal. So it is only natural to want the same goodness in javascript. Luckily there is a framework - linq.js - that provides this functionality. However, the syntax is not quite the same, so it takes a little getting used to.

In this post I want to show an example of how to do a group by.

I have a bunch of people in a collection, each person defined by name, age and job. Now I want to group these people by job. The result should be a grouped collection, where each group contains the person objects belonging to a specific job.

In C# it looks something like this:

var people = new[] {
    new { Name = "Carl", Age = 33, Job = "Tech" },
    new { Name = "Homer", Age = 42, Job = "Tech" },
    new { Name = "Phipps", Age = 35, Job = "Nurse" },
    new { Name = "Doris", Age = 27, Job = "Nurse" },
    new { Name = "Willy", Age = 31, Job = "Janitor" }
};

var grouped = people.GroupBy(
    person => person.Job,
    (job, persons) => new { Job = job, Persons = persons });

foreach (var group in grouped)
{
    System.Diagnostics.Debug.WriteLine("job: " + group.Job);
    foreach (var person in group.Persons)
    {
        System.Diagnostics.Debug.WriteLine("   name: {0}, age: {1}, job: {2}",
            person.Name,
            person.Age,
            person.Job);
    }
}

The group by statement is fairly simple, and the output is exactly as expected:

job: Tech
   name: Carl, age: 33, job: Tech
   name: Homer, age: 42, job: Tech
job: Nurse
   name: Phipps, age: 35, job: Nurse
   name: Doris, age: 27, job: Nurse
job: Janitor
   name: Willy, age: 31, job: Janitor

The same thing in linq.js is a little bit more involved, and for me it did take some playing around before I ended up with the code below. But basically it is quite similar to the C# version.

var people = [
    { name: "Carl", age : 33, job: "Tech" },
    { name: "Homer", age : 42, job: "Tech" },
    { name: "Phipps", age : 35, job: "Nurse" },
    { name: "Doris", age: 27, job: "Nurse" },
    { name: "Willy", age: 31, job: "Janitor" }
];

var grouped = Enumerable
    .From(people)
    .GroupBy(
        function (person) { return person.job; }, // Key selector
        function (person) { return person; },     // Element selector
        function (job, grouping) {                // Result selector
            return {
                job: job,
                persons: grouping.source
            };
        })
    .ToArray();

alert(JSON.stringify(grouped));

And the result:

[{
    "job": "Tech",
    "persons": [{
        "name": "Carl",
        "age": 33,
        "job": "Tech"
    },
    {
        "name": "Homer",
        "age": 42,
        "job": "Tech"
    }]
},
{
    "job": "Nurse",
    "persons": [{
        "name": "Phipps",
        "age": 35,
        "job": "Nurse"
    },
    {
        "name": "Doris",
        "age": 27,
        "job": "Nurse"
    }]
},
{
    "job": "Janitor",
    "persons": [{
        "name": "Willy",
        "age": 31,
        "job": "Janitor"
    }]
}]

2 comments:

Anonymous said...

Very nice.
Your code just saved my day.

Thanks

Unknown said...

awesome

Post a Comment