使用 LINQ 过滤列表
Posted
技术标签:
【中文标题】使用 LINQ 过滤列表【英文标题】:Filter lists with LINQ 【发布时间】:2022-01-12 12:20:36 【问题描述】:我有,列出Students
和Teachers
var students = new List<Student>
new Student
Id= 1,
Name = "AA",
City = "London",
Country = "UK"
,
new Student
Id= 2,
Name = "BB",
City = "New Orleans",
Country = "USA"
var teachers = new List<Teacher>
new Teacher
Id = 1,
Name = "CC",
City = "Berlin",
Country = "Germany"
,
new Teacher
Id = 2,
Name = "DD",
City = "Mexico D.F.",
Country = "Mexico"
我想为每位教师获得一份位于同一国家和同一城市的学生名单。
到目前为止我做了什么:
var result = from teacher in teachers
select new
teacher,
Students = students.Where(s => s.Country == teacher.Country && s.City == teacher.City).ToList()
;
这不起作用,我得到了casting exception
。并尝试:
var result = new List<(Teacher, IEnumerable<Student>)>();
teachers.ToList().ForEach(c => result.Add((c,
students.Where(s => s.Country == c.Country && s.City == c.City).ToList())));
这很好,但是,有没有其他方法,没有循环?
【问题讨论】:
是的,这对于 LINQ 来说是非常可行的。 foreach 不是必需的。使用Select
和Where
的组合,您可以获得您想要的结果。 var teachersWithStudents = teachers.Select(teacher => new teacher, Students = students.Where(s => s.Country == teacher.Country && s.City == teacher.City).ToList() ).ToList()
澄清一下,linq 也是一个 foreach,当你执行 ToList 时,你循环抛出所有列表相同 :) 但是是的 @nbokmans 解决方案应该可以工作
@nbokmans 得到了System.InvalidCastException : Unable to cast object of type System.Collections.Generic.List1[<>f__AnonymousType02[Teacher, System.Collections.Generic.List1[Student]]] to type System.Collections.Generic.IEnumerable1[System.ValueTuple2[Teacher,System.Collections.Generic.IEnumerable1[Student]]]'.
@Alen.Toma 我相信@nbokmans 在 OP 的问题中引用了 .Tolist().ForEach(...)
。说到:ForEach(...)
是List<T>
的void方法,实际上是foreach (x in y)
的语法糖,与LINQ无关
【参考方案1】:
您的 linq 查询是正确的。您的查询返回匿名类型的列表。您不能将其直接转换为元组列表。 您遇到的问题是您尝试转换为哪种类型。如果你想得到像 IEnumerable 这样的元组列表的结果,你应该编写如下代码:
var result = from teacher in teachers
select (
teacher,
students.Where(s => s.Country == teacher.Country && s.City == teacher.City).ToList()
);
那么, result.ToList() 会给你一个元组列表, result.ToArray() 会给你一个元组数组
Lambda 表达式替代:
var result = teachers
.Select(teacher => (teacher, students.Where(s => s.Country == teacher.Country && s.City == teacher.City).ToList()));
但是,我更喜欢匿名列表作为返回类型而不是元组。
【讨论】:
以上是关于使用 LINQ 过滤列表的主要内容,如果未能解决你的问题,请参考以下文章