Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 支票是可数的<;T>;有5个或更多匹配项_C#_Linq_Lambda_Count - Fatal编程技术网

C# 支票是可数的<;T>;有5个或更多匹配项

C# 支票是可数的<;T>;有5个或更多匹配项,c#,linq,lambda,count,C#,Linq,Lambda,Count,我有一个IEnumerable,其中T是一个复杂的对象。我需要检查列表中是否有5个或更多项与lambda表达式匹配。目前,我正在使用类似以下内容: if(myList.Count(c=> c.PropertyX == desiredX && c.Y != undesiredY) >= 5)... 然而,我的列表增长到包含10K+个对象,这成为一个巨大的瓶颈,很可能它在前100个项目中找到了匹配项(但我不能这样假设) 如何才能尽可能有效地执行此操作。您可以使用Wher

我有一个IEnumerable,其中T是一个复杂的对象。我需要检查列表中是否有5个或更多项与lambda表达式匹配。目前,我正在使用类似以下内容:

if(myList.Count(c=> c.PropertyX == desiredX && c.Y != undesiredY) >= 5)...
然而,我的列表增长到包含10K+个对象,这成为一个巨大的瓶颈,很可能它在前100个项目中找到了匹配项(但我不能这样假设)


如何才能尽可能有效地执行此操作。

您可以使用
Where
进行筛选,然后
跳过前4个匹配项,并使用
Any
,一旦找到第5个匹配项就会停止迭代。但是,如果少于5个匹配项,则仍然需要迭代整个列表

if(myList.Where(c=> c.PropertyX == desiredX && c.Y != undesiredY).Skip(4).Any())

您可以使用
Skip
4个元素并检查集合中是否有其他元素。这样,您就不会计算集合中的全部元素

var result = myList.Where(c=>c.PropertyX == desiredX && c.Y != undesiredY);

if(result.Skip(4).Any())
{
    //has >= 5 elements.
}

使用一个普通的旧for循环遍历列表怎么样

int count = 0;
for (int i = 0; i < myList.Count; ++i)
{
    if (myList[i].PropertyX == desiredX && myList[i].Y != undesiredY)
       count++;

    if (count == 5)
       break;
}
int count=0;
对于(int i=0;i

这应该和它在单个线程上运行的速度差不多。由于您无法假设这些项目在列表中的位置,因此算法的时间复杂度不会比O(n)好,其中n是列表中的项目数,即在最坏情况下,您可能必须遍历整个列表。没有比使用我知道的for循环更快的迭代列表的方法了:)

它确保列表中有5个以上,而不是5个或更多。@juharr Yep我看不出他想要>=,谢谢你提到它。谢谢大家-在我多年的编程中从未使用过skip。。。我没有理由!你真的想得到这五个并用它们做些什么吗?或者,一旦有五个匹配项,你会处理所有的事情吗?我注意到,在一些答案中,它会检查它们是否存在,但实际上会将它们扔掉,这意味着如果你需要它们,你可能会再次执行谓词,如果你可能要检查很多对象,那么这可能是无效的……我正在抓取一个列表,列出我当前想要处理的所有对象(500-10K对象)。然后,我需要检查该列表,以确保该列表中每个项目类型至少有5个。如果没有,我会让用户知道这个集合没有最小数量的X类型的项目。然后我会继续使用更大的集合。啊,酷。然后跳过/任何检查都是良好的性能。我考虑过这一点-如果归结为需要比
skip
更快的东西,我会回来尝试一下。什么是
c
?您是否遗漏了var c=myList[i]?很好用。将使用此方法的CPU时间从5%减少到1.5%。仍然需要找到一种方法使其更高效,但这将暂时奏效。如果您想使其更高效,您可能不想使用linq。您在上面的注释中说,您正在检查每种项目类型中至少有五种,这表明您正在多次执行此操作,这意味着重复迭代这些开始对象。您最好只搜索列表,并在执行过程中记录您感兴趣的每个项目,这样您可以在一次迭代中完成所有检查,而多次使用where/skip/any代码将为每个项目迭代列表(直到满足条件为止)@Chris,假设列表的内容不变,您可以通过将
Any
调用的结果赋给一个要重用的变量来判断它。@juharr:我不确定我是否遵循了。我在哪里做出了这样的假设?
任何调用的结果都是bool,那么将其分配给变量有什么帮助呢?@Chris,我想我不明白你的意思。这将只对列表进行一次迭代,因此如果您多次调用它,它只会对列表进行多次迭代,这就是我假设您所说的。它比Count更有效的地方在于,一旦找到第5个匹配项,它将停止迭代列表。