var filteredStudent = new List<Student>();
string description = "Managing the Course";
foreach (var student in students)
{
if (student.subjetcs.Any(x => x.Sylabus.Name.Contains("Critical")))
{
if (student.subjetcs.Any(x => x.Sylabus.Name.Contains("Critical") &&
description.Contains(x.Description)))
{
filteredStudent.Add(student);
}
}
else
{
filteredStudent.Add(student);
}
}
是否可以用单个Linq语句替换所有上述逻辑?
因为我对Linq很感兴趣
答案 0 :(得分:2)
第一步:简化您的逻辑。第一步,摆脱Name.Contains("Critical")
的冗余检查。当你到达那里时,你绝对肯定Name包含“Critical”。
所以标准是 - 如果名称不包含“严重”OR(即,如果符号),则描述匹配。并且,如果你考虑它,这意味着括号中的位(“即,如果......”)变得无关紧要。如果描述匹配,那么我们总是添加学生是否包含“严重”。我们还添加了一个没有“Critical”的那个可以呈现为:
更新:octavioccl指出错误。
var filteredStudent = students
.Where(s=>!s.subjects.Any(x => x.Sylabus.Name.Contains("Critical") ||
description.Contains(x.Description)))
.ToList();
注意:鉴于对上述内容的更新,下半部分可能会比上半部分更快,所以我们可能应该对它们进行反转。
var filteredStudent = students
.Where(s=>s.subjects
.Any(x =>
description.Contains(x.Description) ||
!x.Sylabus.Name.Contains("Critical")))
.ToList();
更新(再次)
一夜之间想到这一点,我意识到这不起作用。那么,让我们再试一次......
- 我们希望所有学生除了那些主题包含“严重”的学生,除非该课程的描述匹配。
(重要提示 - 尽管有一种名为Except()
的Linq方法不是我们想要的 - 我们实际上想要不在哪里。
所以,首先要做的是:
var filteredStudent = students
.Where(s=>!s.subjects.Any(x =>
x.Sylabus.Name.Contains("Critical")
? !description.Contains(x.Description)
: false)
.ToList();
所以,这里最内部的lambda(x =>
...)是一个测试,如果一个特定的主题是拒绝学生的理由。如果它不包含“严重”,则可以(通过最后的false
)。如果是,则如果描述不匹配则拒绝。
然而,从这里我们可以缩短它。考虑一下我们刚才所说的,如果第一次测试是假的,那么整件事就是假的。如果第一次测试是真的,那么基于第二次测试,整个表达式是真的还是假的 - 这正是“短路和”的定义,因此:
var filteredStudent = students
.Where(s=>!s.subjects.Any(x =>
x.Sylabus.Name.Contains("Critical")
&& !description.Contains(x.Description))
.ToList();
请阅读我们得到的结论,“除了那些正在接受Sylabus名称包含”严重“但没有相应描述的主题的学生外,我们会接受所有学生。
答案 1 :(得分:1)
添加到结果列表的条件如下:
Sylabus.Name
不包含&#34;严重&#34;或Sylabus.Name
包含&#34;严重&#34;description
包含Description
。
这可以编码为单个Where
条件。
答案 2 :(得分:0)
我不明白为什么要重复这个条件:student.subjects.Any(x => x.Syllabus.Name.Contains("Critical"))
,然后使用相同的结果:filteredStudent.Add(student)
?
如果要添加列表中的所有项目,请执行以下操作:
students.ToList().ForEach(s => filteredStudent.Add(s));
如果要过滤结果,请添加Where
:
students.Where(s => s.subjetcs.Any(x => x.Sylabus.Name.Contains("Critical") && description.Contains(x.Description)))
.ToList().ForEach(s => filteredStudent.Add(s));
也许你想要这样的东西:
var list = new List<Stundent>();
list.AddRange(studnets.Where(s => s.subjetcs.Any(x => x.Sylabus.Name.Contains("Critical") && description.Contains(x.Description)));
list.AddRange(studnets.Where(s => s.subjetcs.All(x => !x.Sylabus.Name.Contains("Critical")));
list.ForEach(x => filteredStudent.Add(x));
OR:
students.Where(s => s.subjetcs.Any(x => x.Sylabus.Name.Contains("Critical") && description.Contains(x.Description)) || s.subjetcs.All(x => !x.Sylabus.Name.Contains("Critical"))
.ToList().ForEach(s => filteredStudent.Add(s));