c# - .NET 是否具有用于多个集合的内置 IEnumerable?

标签 c# .net ienumerable

我需要一种简单的方法来迭代多个集合而不实际合并它们,但我找不到任何内置到 .NET 中的东西看起来像这样做。感觉这应该是比较普遍的情况。我不想重新发明轮子。有没有内置的东西可以做这样的事情:

public class MultiCollectionEnumerable<T> : IEnumerable<T>
{
    private MultiCollectionEnumerator<T> enumerator;
    public MultiCollectionEnumerable(params IEnumerable<T>[] collections)
    {
        enumerator = new MultiCollectionEnumerator<T>(collections);
    }

    public IEnumerator<T> GetEnumerator()
    {
        enumerator.Reset();
        return enumerator;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        enumerator.Reset();
        return enumerator;
    }


    private class MultiCollectionEnumerator<T> : IEnumerator<T>
    {
        private IEnumerable<T>[] collections;
        private int currentIndex;
        private IEnumerator<T> currentEnumerator;

        public MultiCollectionEnumerator(IEnumerable<T>[] collections)
        {
            this.collections = collections;
            this.currentIndex = -1;
        }

        public T Current
        {
            get
            {
                if (currentEnumerator != null)
                    return currentEnumerator.Current;
                else
                    return default(T);
            }
        }

        public void Dispose()
        {
            if (currentEnumerator != null)
                currentEnumerator.Dispose();
        }

        object IEnumerator.Current
        {
            get
            {
                return Current;
            }
        }

        public bool MoveNext()
        {
            if (currentIndex >= collections.Length)
                return false;
            if (currentIndex < 0)
            {
                currentIndex = 0;
                if (collections.Length > 0)
                    currentEnumerator = collections[0].GetEnumerator();
                else
                    return false;
            }
            while (!currentEnumerator.MoveNext())
            {
                currentEnumerator.Dispose();
                currentEnumerator = null;

                currentIndex++;
                if (currentIndex >= collections.Length)
                    return false;
                currentEnumerator = collections[currentIndex].GetEnumerator();
            }
            return true;
        }

        public void Reset()
        {
            if (currentEnumerator != null)
            {
                currentEnumerator.Dispose();
                currentEnumerator = null;
            }
            this.currentIndex = -1;
        }
    }

}

最佳答案

试试3.5新增的SelectMany扩展方法

IEnumerable<IEnumerable<int>> e = ...;
foreach ( int cur in e.SelectMany(x => x)) {
  Console.WriteLine(cur);
}

代码 SelectMany(x => x) 具有将集合的集合展平为单个集合的效果。这是以懒惰的方式完成的,并允许如上所示的直接处理。

如果您只有 C# 2.0 可用,则可以使用迭代器来获得相同的结果。

public static IEnumerable<T> Flatten<T>(IEnumerable<IEnumerable<T>> enumerable) {
  foreach ( var inner in enumerable ) {
    foreach ( var value in inner ) {
      yield return value;
    }
  }
}

关于c# - .NET 是否具有用于多个集合的内置 IEnumerable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2862040/

相关文章:

c# - 为什么更喜欢在 IQueryable 上使用 linq 而不是在 IEnumerable 上使用 linq?

c# - 使用 C# 或 SQL 复制 Access 表结构和约束

c# - 如何从存储过程返回一个数组?

c# - 确定 XDocument 中的元素

c# - 使用在 C# .net 4 中的多个 XSD 文件中定义的复杂类型从 XSD 创建数据表

c# - 以编程方式转储调用堆栈

c# - 食人族类(class)

c# - 如何避免 Masterpage 的 url 重写

c# - 在c#中,如何在多线程环境下迭代IEnumerable

c# - Scala 中 IEnumerable LINQ 等价物的图表?