我有一个看起来像这样的课程:
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()
执行此操作?
答案 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);