获取IEnumerable<T>计数的最佳方法

33

如何在不枚举集合中的所有项的情况下获取IEnumerable集合中项目的计数?

是否可以通过LINQ或Lambda实现?


1
可能是重复的问题:如何在不迭代的情况下计算 IEnumerable<T> 中的项数? - Chris Pietschmann
11个回答

20

无论如何,你都必须循环遍历它。Linq提供了Count方法:

var result = myenum.Count();

3
没错,只要文件开头有"using System.Linq;",这个代码就可以运行。如果没有Linq,代码就无法执行。 - user1961169
如何在调试控制台中执行? - serge

17
解决方案取决于不希望枚举集合的原因。如果是因为枚举集合可能很慢,那么没有比这更快的解决方案。如果可能的话,您可以考虑使用ICollection。除非枚举非常慢(例如,它从磁盘读取项),否则速度不应该成为问题。
如果之所以不想枚举集合是因为需要编写更多代码,那么您可以使用.Count()扩展方法,这个方法已经为您编写好了。只需使用MyEnumerable.Count()即可。
如果之所以不想枚举集合是因为想要在计数后能够枚举集合,那么.Count()扩展方法允许这样做。您甚至可以在枚举集合的过程中调用.Count(),它将从计数前继续进行枚举。例如:
foreach (int item in Series.Generate(5))
{
    Console.WriteLine(item + "(" + myEnumerable.Count() + ")");
}

将会给出结果。

0(5)

1(5)

2(5)

3(5)

4(5)

如果这是因为枚举具有副作用(例如写入磁盘/控制台)或者依赖于在计数和枚举之间可能会更改的变量(例如从磁盘读取),[注:如果可能的话,建议重新思考架构,因为这可能会引起很多问题]那么可以考虑将枚举值读入到一个中间存储器中。例如:

List<int> seriesAsList = Series.Generate(5).ToList();

以上所有内容都假设您不能更改类型(即它是从您不拥有的库中返回的)。如果可能,您可能希望考虑更改为使用 ICollection 或 IList(ICollection 的范围比 IList 更广),它具有 Count 属性。


16

你需要枚举才能得到计数。像List这样的结构可以保留运行计数。


如果在方法中传递了IEnumerable变量,则variable.Count()对我有效。 - Vikram Shetty
据我所知,那是不可能的。你确定你没有在某个地方进行强制类型转换吗? - Sinjai
对于 IEnumerable<T> 变量,必须使用 variable.Count<T>() 来获取元素数量,或者如果只是检查是否存在任何元素,则使用 variable.Any<T>()。 - Sylwester Santorowski

6

使用这个。

IEnumerable list =..........;

list.OfType<T>().Count()

它将返回计数。


给一个 IEnumerable 命名为 list 至少是令人困惑的。 - Theodor Zoulias

1

这也取决于您通过计数想要实现什么。如果您想查找可枚举集合是否有任何元素,可以使用

myEnumerable.Any() 而不是 myEnumerable.Count(),前者将产生第一个元素,后者将产生所有元素。


1

如果您需要获取完整计数,则必须遍历每个项。如果您只需要检查 IEnumerable 中是否有一个或多个项,则更有效的方法是检查是否有任何项。 Any() 仅检查是否存在值,而不会遍历所有内容。

IEnumerable myStrings = new List(){"one","two", "three"};

bool hasValues = myStrings.Any();


1

如果你想使用一个仍然有些灵活的结构,但也具有所需功能的构造,还可以使用IList或ICollection。它们都意味着IEnumerable。


0

LINQ 无法实现此功能,因为调用 .Count(...) 会枚举集合。如果您遇到无法对集合进行两次迭代的问题,请尝试以下方法:

List<MyTableItem> myList = dataContext.MyTable.ToList();
int myTableCount = myList.Count;

foreach (MyTableItem in myList)
{
   ...
}

0

我认为最好的解决方案是执行以下操作:

  1. 使用 System.Linq.Dynamic;
  2. myEnumerable.AsQueryable().Count()。

4
错误的。那不比其他任何东西更好,而且可能更糟糕。 - SLaks
还是一样的问题.. 如果我们只需要计数,而且因为我们不想迭代每个记录.. 为什么?因为我们想要快速.. - nrs

0
如果你需要计数然后循环,使用列表可能更好。
如果你正在使用计数来检查成员,可以使用Any()来避免枚举整个集合。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接