tags:

views:

433

answers:

4

The MSDN explains Lookup like this:

A Lookup<TKey, TElement> resembles a Dictionary<TKey, TValue>. The difference is that a Dictionary<TKey, TValue> maps keys to single values, whereas a Lookup<TKey, TElement> maps keys to collections of values.

I don't find that explanation particularly helpful. What is Lookup used for?

+18  A: 

It's a cross between an IGrouping and a dictionary. It lets you group items together by a key, but then access them via that key in an efficient manner (rather than just iterating over them all, which is what GroupBy lets you do).

For example, you could take a load of .NET types and build a lookup by namespace... then get to all the types in a particular namespace very easily:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;

public class Test
{
    static void Main()
    {
        // Just types covering some different assemblies
        var sampleTypes = new[] { typeof(List<>), typeof(string), 
                                  typeof(Enumerable), typeof(XmlReader) };

        // All the types in those assemblies
        var allTypes = sampleTypes.Select(t => t.Assembly)
                                  .SelectMany(a => a.GetTypes());

        // Grouped by namespace, but indexable
        var lookup = allTypes.ToLookup(t => t.Namespace);

        foreach (var type in lookup["System"])
        {
            Console.WriteLine("{0}: {1}", 
                              type.FullName, type.Assembly.GetName().Name);
        }
    }
}
Jon Skeet
+1 Awesome Explanation.
Kyle Rozendo
I think to make this answer better you could replace some of the vars. For learning purposes I think it is easier to follow, when the types are expressed clearly. Just my 2 cents :)
Alex Baranosky
+2  A: 

I haven't successfully used it before, but here is my go:

A Lookup<TKey, TElement> would behave pretty much like a (relational) database index on a table without a unique constraint. Use it in the same places you would use the other.

Daren Thomas
+7  A: 

One way to think about it is this: Lookup<TKey, TElement> is similar to Dictionary<TKey, Collection<TElement>>. Basically a list of zero or more elements can be returned via the same key.

namespace LookupSample
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    class Program
    {
        static void Main(string[] args)
        {
            List<string> names = new List<string>();
            names.Add("Smith");
            names.Add("Stevenson");
            names.Add("Jones");

            ILookup<char, string> namesByInitial = names.ToLookup((n) => n[0]);

            // count the names
            Console.WriteLine("J's: {0}", namesByInitial['J'].Count());
            Console.WriteLine("S's: {0}", namesByInitial['S'].Count());
            Console.WriteLine("Z's: {0}", namesByInitial['Z'].Count());
        }
    }
}
bobbymcr
Can there be zero elements in a lookup result? How would you get that? (Lookup is publicly immutable as far as I can tell, and I don't think ToLookup would effectively invent keys.)
Jon Skeet
Technically, yes, since a Lookup returns an empty collection for a non-existent key (I edited my post to add a code sample that shows this).
bobbymcr
+2  A: 

I guess you could argue it this way: imagine you're creating a data structure to hold the contents of a phone book. You want to key by lastName and then by firstName. Using a dictionary here would be dangerous because many people can have the same name. So a Dictionary will always, at most, map to a single value.

A Lookup will map to potentially several values.

Lookup["Smith"]["John"] will be a collection of size one billion.

David Andres