ToLookup有多个键(ToLookup with multiple keys)

2019-07-29 15:02发布

有没有要求对多个按键的方式.ToLookup通过LINQ提供的功能?

我承认,这似乎不直观,在第一,和我期待的是有这样做没有实际的方式,但我希望有人知道的一种方式。

基本上,我希望能够通过两个值来查找,例如stringint与这两个值,并检索对象。

    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 1:

我会用Tuple S表示这样的事情:

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)];


Answer 2:

所以其他的答案是沿着我在想台词,但它是有点麻烦要创建一个元组或匿名类你想只得到一个值从查找各一次。 那岂不是巨大的,如果你能只是坚持一个字符串和一个int入索引来获取值了。 通过创建自己的类索引器,你可以做到这些包裹查找。

public class MyLookup<T1, T2, TOut>
{
    private ILookup<Tuple<T1, T2>, TOut> lookup;
    public MyLookup(IEnumerable<TOut> source, Func<TOut, Tuple<T1, T2>> keySelector)
    {
        lookup = source.ToLookup(keySelector);
    }

    public IEnumerable<TOut> this[T1 first, T2 second]
    {
        get
        {
            return lookup[Tuple.Create(first, second)];
        }
    }

    //feel free to either expose the lookup directly, or add other methods to access the lookup
}

这里是它正在使用的一个示例:

IEnumerable<MyClass> data = null; //TODO populate with real data
var lookup = new MyLookup<string, int, MyClass>(data
    , item => Tuple.Create(item.StringProp, item.IntProp));

IEnumerable<MyClass> someValue = lookup["c", 4];


Answer 3:

虽然不是你真正想要的,但会做的工作就好了:

var r = set.ToLookup(x => new { x.StringProp, x.IntProp });
var f = r[ new { StringProp = "a", IntProp = 1 } ].First();


文章来源: ToLookup with multiple keys
标签: c# .net lookup