Using the .ToDictionary() Extension Method

Last time, I showed how you can use the Cast() extension method defined on IEnumerable/IEnumerable(Of T) to do an element conversion for a sequence that implements one of the enumerable interfaces.

Today I want to talk about the ToDictionary extension method. This extension method lets you take a sequence that implements IEnumerable(Of T) and build a dictionary out of the elements of the sequence, allowing you to specify the key for each element. The key is the hash for the dictionary.

For example, consider the following code:

 Class Car
    Public id As Integer
    Public manufacturer As String
    Public color As String
End Class

Function GetCars() As List(Of Car)

    Dim ret = New List(Of Car)
    ret.Add(New Car With {.id = 1, .manufacturer = "Toyota", .color = "Red"})
    ret.Add(New Car With {.id = 2, .manufacturer = "Honda", .color = "Red"})

    Return ret
End Function

Sub Main()
    Dim cars = GetCars()
    Dim dictionary = cars.ToDictionary(Function(c) c.id)
End Sub

This simple example builds a list of cars. We then get this list in Main(), and assign it to the variable "cars". Then we use type inference and assign to dictionary the value returned from the ToDictionary() extension method. This method returns a IDictionary(Of K, V), and in this case, the type argument V is inferred to be Car, and the type argument K is inferred based on the result of the lambda expression. Here, since we're returning the ID, it's going to be an integer.

Thus the final type of dictionary is IDictionary(Of Integer, Car). Neat eh? Type inference is really awesome because it allows you to "just let the compiler do its work".

You can then use dictionary like you would use any other IDictionary: you can retrieve elements using the () accessor, etc, etc. Play around with it, and see how powerful this extension method is.

Aside: how does the ToDictionary extension method work?

The ToDictionary method creates a new Dictionary(Of K, V) and adds elements to the dictionary, using the lambda expression you supplied to get the value of the key. Since the compiler has resolved all the type parameters at the call site (using both the hints from IEnumerable(Of T) and the lambda expression), you do not need to specify any type arguments.

Since your lambda expression is used to get the key value, this implies that your lambda expression should return values that are "good hashes".

 

Technorati Tags: LINQ, VB9, VisualBasic