ToLookup with multiple keys

Merwer picture Merwer · May 29, 2012 · Viewed 11.5k times · Source

Is there a way to require multiple keys for the .ToLookup function provided by LINQ?

I will admit that this seems non-intuitive at first, and I'm expecting that there's no actual way to do this, but I'm hoping that someone knows a way.

I basically want to be able to lookup by two values, for example a string and an int, and retrieve the object with those two values.

Example

    public class MyClass {
      public string StringProp {get;set;}
      public int IntProp {get;set;}
      public object MoreData {get;set;}
    }

    public class Main {
      public void Main() {
        HashSet<MyClass> set = new HashSet<MyClass>();
        set.Add(new MyClass {StringProp = "a", IntProp = 1, MoreData = null});
        set.Add(new MyClass {StringProp = "c", IntProp = 4, MoreData = new object()});
        set.Add(new MyClass {StringProp = "a", IntProp = 2, MoreData = "upupdowndown"});
        set.Add(new MyClass {StringProp = "c", IntProp = 1, MoreData = string.Empty});
        set.Add(new MyClass {StringProp = "c", IntProp = 4, MoreData = string.Empty});
        // Using 'var' because I don't know how this would be defined.
        // I recognize that this will not compile - but this is what I'm trying to do.
        var lookup = set.ToLookup(x => x.StringProp && x.IntProp)
        MyClass c = lookup["a", 1].First(); // Should return the first element
        IEnumerable<MyClass> list = lookup["c", 4]; // Should return the 2nd and last elements
      }
    }

Answer

Gabe picture Gabe · May 29, 2012

I would use Tuples for this sort of thing:

var lookup = set.ToLookup(x => Tuple.Create(x.StringProp, x.IntProp));
MyClass c = lookup[Tuple.Create("a", 1)].First();
IEnumerable<MyClass> list = lookup[Tuple.Create("c", 4)];