从IEnumerable 「T」计算项目而不迭代?

本文翻译自:Count the items from a IEnumerable without iterating?

private IEnumerable<string> Tables
{
    get
    {
        yield return "Foo";
        yield return "Bar";
    }
}

Let's say I want iterate on those and write something like processing #n of #m. 假设我想迭代那些并写一些像#m的#n处理。

Is there a way I can find out the value of m without iterating before my main iteration? 有没有一种方法可以在我的主迭代之前找到m的值而不进行迭代?

I hope I made myself clear. 我希望我清楚自己。


#1楼

参考:https://stackoom.com/question/hwD/从IEnumerable-T-计算项目而不迭代


#2楼

Result of the IEnumerable.Count() function may be wrong. IEnumerable.Count()函数的结果可能是错误的。 This is a very simple sample to test: 这是一个非常简单的测试样本:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;

namespace Test
{
  class Program
  {
    static void Main(string[] args)
    {
      var test = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
      var result = test.Split(7);
      int cnt = 0;

      foreach (IEnumerable<int> chunk in result)
      {
        cnt = chunk.Count();
        Console.WriteLine(cnt);
      }
      cnt = result.Count();
      Console.WriteLine(cnt);
      Console.ReadLine();
    }
  }

  static class LinqExt
  {
    public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> source, int chunkLength)
    {
      if (chunkLength <= 0)
        throw new ArgumentOutOfRangeException("chunkLength", "chunkLength must be greater than 0");

      IEnumerable<T> result = null;
      using (IEnumerator<T> enumerator = source.GetEnumerator())
      {
        while (enumerator.MoveNext())
        {
          result = GetChunk(enumerator, chunkLength);
          yield return result;
        }
      }
    }

    static IEnumerable<T> GetChunk<T>(IEnumerator<T> source, int chunkLength)
    {
      int x = chunkLength;
      do
        yield return source.Current;
      while (--x > 0 && source.MoveNext());
    }
  }
}

Result must be (7,7,3,3) but actual result is (7,7,3,17) 结果必须是(7,7,3,3),但实际结果是(7,7,3,17)


#3楼

I used such way inside a method to check the passed in IEnumberable content 我在方法中使用这种方式检查传入的IEnumberable内容

if( iEnum.Cast<Object>().Count() > 0) 
{

}

Inside a method like this: 在这样的方法内:

GetDataTable(IEnumberable iEnum)
{  
    if (iEnum != null && iEnum.Cast<Object>().Count() > 0) //--- proceed further

}

#4楼

No, not in general. 不,不是一般的。 One point in using enumerables is that the actual set of objects in the enumeration is not known (in advance, or even at all). 使用枚举的一点是,枚举中的实际对象集是未知的(事先,甚至根本不知道)。


#5楼

IEnumerable doesn't support this. IEnumerable不支持这个。 This is by design. 这是设计的。 IEnumerable uses lazy evaluation to get the elements you ask for just before you need them. IEnumerable使用延迟评估来获取您在需要之前请求的元素。

If you want to know the number of items without iterating over them you can use ICollection<T> , it has a Count property. 如果你想知道没有迭代它们的项目数,你可以使用ICollection<T> ,它有一个Count属性。


#6楼

A friend of mine has a series of blog posts that provide an illustration for why you can't do this. 我的一位朋友有一系列博客文章,说明了为什么你不能这样做。 He creates function that return an IEnumerable where each iteration returns the next prime number, all the way to ulong.MaxValue , and the next item isn't calculated until you ask for it. 他创建了返回IEnumerable的函数,其中每次迭代返回下一个素数,一直到ulong.MaxValue ,并且直到你要求它才计算下一个项目。 Quick, pop question: how many items are returned? 快速流行问题:返回了多少项?

Here are the posts, but they're kind of long: 这是帖子,但它们有点长:

  1. Beyond Loops (provides an initial EnumerableUtility class used in the other posts) Beyond循环 (提供其他帖子中使用的初始EnumerableUtility类)
  2. Applications of Iterate (Initial implementation) 迭代的应用 (初始实现)
  3. Crazy Extention Methods: ToLazyList (Performance optimizations) 疯狂扩展方法:ToLazyList (性能优化)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值