使用列表列表作为IEnumerable <t> .ToLookup()的查找属性</t>

时间:2011-12-08 01:57:28

标签: c# .net linq ienumerable

我有一个看起来像这样的课程:

public class Person 
{
    public string Name { get; set; }
    public DateTime Birthdate { get; set; }
    public List<string> PersonalEffects {get; set; }
}

我有一个List<Person>,我想使用IEnumerable<T>.ToLookup()并使用每个效果的名称作为关键字,并将具有该效果的字符作为值。样本输出:

Cutlass (the Effect)
Jack Sparrow (Person)
Will Turner

Pistol
Jack Sparrow
Hector Barbossa
Davy Jones

然而,我的LINQ-fu让我失望了。我可以通过一个字典和一些ForEach循环来做到这一点,但它看起来并不干净(尽管它最终会成为同样的东西)。

如何在C#中使用ToLookup()执行此操作?

3 个答案:

答案 0 :(得分:3)

这样可行:

persons.SelectMany(p => p.PersonalEffects.Select(e => new { Person = p, Effect = e }))
       .ToLookup(o => o.Effect, o => o.Person);

我们在这里所做的基本上是人和效果的结合,创造人与效果对(每个特定的人和效果都可以出现在多对中),然后通过效果对这些对进行分组并收集每个对的人。以可枚举的顺序产生影响。

答案 1 :(得分:1)

基本上,您必须先将列表展平成对。您可以使用很少使用(至少对我来说)SelectMany()重载:

List<Person> people = ...
var lookup = people.SelectMany(p => p.PersonalEffects, 
                              (p, c) => new { Name = p.Name, Effect = c.Name })
                   .ToLookup(e => e.Effect, e => e.Name)

答案 2 :(得分:1)

以前的答案的查询理解语法为好奇:

ILookup<string, string> lookup =
  (
    from p in people
    from e in p.PersonalEffects
    select new { Name = p.Name, Effect = e }
  ).ToLookup(x => x.Effect, x => x.Name);