【问题标题】:The best way to get a count of IEnumerable<T>获取 IEnumerable<T> 计数的最佳方法
【发布时间】:2010-09-06 22:11:03
【问题描述】:

在不枚举集合中的所有项目的情况下获取 IEnumerable 集合中的项目计数的最佳/最简单方法是什么?

可以使用 LINQ 或 Lambda 吗?

【问题讨论】:

标签: c# linq


【解决方案1】:

在任何情况下,您都必须遍历它。 Linq 提供了Count 方法:

var result = myenum.Count();

【讨论】:

  • 是的,只要你有“使用 System.Linq;”就可以了在文件的开头。没有 Linq,这是行不通的。
【解决方案2】:

解决方案取决于您不想枚举集合的原因。

如果是因为枚举集合可能很慢,那么没有更快的解决方案。如果可能,您可能要考虑使用 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)

如果是因为枚举具有副作用(例如,写入磁盘/控制台)或依赖于可能在计数和枚举之间发生变化的变量(例如,从磁盘读取)[N.B.如果可能的话,我建议重新考虑架构,因为这会导致很多问题] 然后考虑的一种可能性是将枚举读入间歇性存储。例如:

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

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

【讨论】:

    【解决方案3】:

    您必须枚举才能获得计数。其他结构(如 List)保持运行计数。

    【讨论】:

    • 如果将 IEnumerable 变量传递给方法,那么 variable.Count() 对我有用。
    • @Vikram 据我所知,这不可能。你确定你没有在某个地方投射?
    • 对于 IEnumerable 变量,它必须是 variable.Count() 或者如果你只是检查是否有任何元素 variable.Any()
    【解决方案4】:

    使用这个。

    IEnumerable list =..........;
    
    list.OfType<T>().Count()
    

    它将返回计数。

    【讨论】:

    • 将名称 list 命名为 IEnumerable 至少可以说是令人困惑。
    【解决方案5】:

    还有 IList 或 ICollection,如果您想使用仍然有些灵活但也具有您需要的功能的构造。它们都暗示 IEnumerable。

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

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

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

        bool hasValues = myStrings.Any();

        【讨论】:

          【解决方案8】:

          无法使用 LINQ,因为调用 .Count(...) 确实会枚举集合。如果您遇到无法遍历集合两次的问题,请尝试以下操作:

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

          【讨论】:

            【解决方案9】:

            如果您需要计数然后循环,则最好使用列表。

            如果您使用 count 来检查成员,您可以使用 Any() 来避免枚举整个集合。

            【讨论】:

              【解决方案10】:

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

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

              【讨论】:

              • 错了。这并不比其他任何事情都好,而且可能更糟。
              • 还是一样.. 如果我们只需要 Count 怎么办,因为我们不想迭代每条记录.. 为什么?因为我们想要快..
              【解决方案11】:

              当我想使用 Count 属性时,我使用实现 IEnumerable 和 ICollection 接口的 ILIST。 ILIST 数据结构是一个数组。我逐步使用 VS 调试器,发现下面的 .Count 属性返回 Array.Length 属性。

              IList<string> FileServerVideos = Directory.GetFiles(VIDEOSERVERPATH, "*.mp4"); 
              if (FileServerVideos.Count == 0)
                  return;
              

              【讨论】:

                猜你喜欢
                • 2010-10-04
                • 2011-10-19
                • 1970-01-01
                • 1970-01-01
                • 2013-02-21
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多