[英]Does .NET have a built in IEnumerable for multiple collections?
I need an easy way to iterate over multiple collections without actually merging them, and I couldn't find anything built into .NET that looks like it does that. 我需要一种简单的方法来迭代多个集合而不实际合并它们,我找不到任何内置于.NET中的内容。 It feels like this should be a somewhat common situation.
感觉这应该是一种常见的情况。 I don't want to reinvent the wheel.
我不想重新发明轮子。 Is there anything built in that does something like this:
有什么内置的东西是这样的:
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;
}
}
}
Try the SelectMany extension method added in 3.5. 尝试在3.5中添加的SelectMany扩展方法。
IEnumerable<IEnumerable<int>> e = ...;
foreach ( int cur in e.SelectMany(x => x)) {
Console.WriteLine(cur);
}
The code SelectMany(x => x)
has the effect of flattening a collection of collections into a single collection. 代码
SelectMany(x => x)
具有将集合集合展平为单个集合的效果。 This is done in a lazy fashion and allows for straight forward processing as shown above. 这是以懒惰的方式完成的,并允许如上所示的直接处理。
If you only have C# 2.0 available, you can use an iterator to achieve the same results. 如果只有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;
}
}
}
Just use the Enumerable.Concat()
extension method to "concatenate" two IEnumerables. 只需使用
Enumerable.Concat()
扩展方法来“连接”两个IEnumerables。 Don't worry, it doesn't actually copy them into a single array (as you might infer from the name), it simply allows you to enumerate over them all as if they were one IEnumerable. 不用担心,它实际上并没有将它们复制到一个数组中(正如您可能从名称中推断出来的那样),它只是允许您枚举它们,就像它们是IEnumerable一样。
If you have more than two then Enumerable.SelectMany()
would be better. 如果你有两个以上,那么
Enumerable.SelectMany()
会更好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.