如何使用for循环迭代链接IEnumerable.Where()
本文关键字:IEnumerable Where 链接 迭代 何使用 for 循环 | 更新日期: 2023-09-27 17:57:31
考虑以下代码(尽管有点做作,但它是对真实世界程序的主要简化):
string[] strings = { "ab", "abcd", "abc", "ac", "b", "abcde", "c", "bc" };
string[] filters = { "a", "b", "c" };
// iteratively apply each filter
IEnumerable<string> filteredStrings = strings.ToArray();
foreach (string filter in filters)
{
// in my real-world program lots of processing and stuff
// happens here, hence why i need the enclosing foreach loop
filteredStrings = filteredStrings.Where(s => s.Contains(filter));
}
正如您所看到的,代码迭代地将一个字符串数组筛选为一组较小的字符串。当for每个循环结束时,filteredStrings
应该是通过所有过滤器的字符串的子集。在这个例子中,这将是:
{ "abcd", "abc", "abcde" }
然而,我得到的输出是:
{ "abcd", "abc", "ac", "abcde", "c", "bc" }
它似乎只是过滤掉那些不包含"c"
的字符串,我认为这与它是最后一个过滤器有关。我想我一定没有以正确的方式链接IEnumerable.Where()
。这里发生了什么?我如何获得正确的输出?
是的,根据我代码中的注释,foreach循环需要保持完整。
where委托没有按照您期望的方式捕获本地变量。变量filter
正在更改,它使用所有where中的最后一个结果,因为Linq执行惰性求值。
将迭代变量复制到一个局部var中,我相信它会捕获您期望的方式。
foreach (string filter in filters)
{
string localFilter = filter;
filteredStrings = filteredStrings.Where(s => s.Contains(localFilter));
}
您正在使用一个在循环中修改的变量:filter
创建它的副本:
foreach (string filter in filters)
{
// in my real-world program lots of processing and stuff
// happens here, hence why i need the enclosing foreach loop
string f = filter;
filteredStrings = filteredStrings.Where(s => s.Contains(f));
}