Grouping - VB

[Table of Contents] [Next Topic]

LINQ query expressions look a lot like SQL, and that is intentional.  SQL is a non-procedural query language that many developers are already familiar with, so to the extent that LINQ looks like SQL, it gives developers a familiar frame of reference.

This blog is inactive.
New blog: EricWhite.com/blog

Blog TOCHowever, one of the fundamental differences between LINQ and SQL is that whereas SQL always projects rectangular result sets, LINQ has the capability of projecting hierarchical result sets.

The following code creates an array of an anonymous type containing two properties each.  It then groups them by age.  We can then iterate through the results using nested for loops.  (Following code only compiles with Option Strict Off.)

Dim people() = { _
New With {.Name = "Bob", .Age = 3}, _
New With {.Name = "Bill", .Age = 3}, _
New With {.Name = "Mary", .Age = 4}, _
New With {.Name = "June", .Age = 3}, _
New With {.Name = "Nancy", .Age = 4}, _
New With {.Name = "Shelly", .Age = 4}, _
New With {.Name = "Cheryl", .Age = 3}, _
New With {.Name = "Joe", .Age = 3} _
}
Dim groupedByAge = people.GroupBy(Function(s) s.Age)
For Each group In groupedByAge
' group implements IGrouping
Console.WriteLine("Group of people aged {0}", group.Key)
For Each person In group
' person is an instance of the above anonymous type
Console.WriteLine(person)
Next
Console.WriteLine()
Next

This example produces the following output:

Group of people aged 3
{ Name = Bob, Age = 3 }
{ Name = Bill, Age = 3 }
{ Name = June, Age = 3 }
{ Name = Cheryl, Age = 3 }
{ Name = Joe, Age = 3 }

Group of people aged 4
{ Name = Mary, Age = 4 }
{ Name = Nancy, Age = 4 }
{ Name = Shelly, Age = 4 }

Chunking a Sequence

I mentioned previously that there is an overload of Select that takes a delegate with two parameters, the second being the index of the item.  Now that we have seen project, anonymous objects, and grouping, we can show this little example that uses the second overload of the Select extension method (includes an argument that is an index of each item in the sequence) to chunk any sequence in to segments of arbitrary length.

Let’s say that you are one of those people who want to memorize pi to a few hundred places, and you want to print it out with commas every four digits to make it easier to study and remember.  You can write a query like this:

Dim pi = "3.14159265358979323846"
Console.Write(pi.Substring(0, 2))
Dim q = pi.Substring(2) _
.ToCharArray _
.Select(Function(item, i) New With { .Item = item, .Chunk = Math.Floor(i / 4) }) _
.GroupBy(Function(i) i.Chunk)
For Each g In q
For Each c In g
Console.Write(c.Item)
Next
Console.Write(",")
Next
Console.WriteLine

When run, it produces:

3.1415,9265,3589,7932,3846,

There are lots of options for grouping, and this tutorial won't go into all of them.  However, the notion that we can project a hierarchical result set is important.  Later on in the tutorial, we'll see a new grouping extension method that gives us the ability to group in a way that the standard grouping extension methods don't support.

[Table of Contents] [Next Topic] [Blog Map]

Examples.txt