Reputation: 86134
Is there a simple built-in way to take an ordered list of IEnumerable
s and return a single IEnumerable
which yields, in order, all the elements in the first, then the second, and so on.
I could certainly write my own, but I wanted to know whether there was already a way to accomplish this seemingly useful task before I do it.
Upvotes: 21
Views: 4104
Reputation: 91895
Further to the (correct) LINQ-based answers...
If you don't want to use LINQ, you can invent a ChainedEnumerable class, using yield:
public class ChainedEnumerable<T> : IEnumerable<T>
{
private readonly IEnumerable<T>[] _inners;
public ChainedEnumerable(params IEnumerable<T>[] inners)
{
_inners = inners;
}
public IEnumerator<T> GetEnumerator()
{
foreach (IEnumerable<T> inner in _inners)
{
foreach (T t in inner)
{
yield return t;
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Use it like this:
List<string> a = new List<string> { "A1", "A2", "A3" };
List<string> b = new List<string> { "B1", "B2", "B3" };
ChainedEnumerable<string> chainedEnumerable =
new ChainedEnumerable<string>(a, b);
foreach (string s in chainedEnumerable)
Console.WriteLine(s);
Upvotes: 15
Reputation: 1063754
Further to JaredPar's (correct) answer - also query syntax:
var all = from inner in outer
from item in inner
select item;
Upvotes: 15
Reputation: 755259
Try SelectMany.
IEnumerable<int> Collapse(IEnumerable<IEnumerable<int>> e){
return e.SelectMany(x => x );
}
The purpose of this function is to flatten a group of IEnumerable<IEnumerable<T>> into an IEnumerable<T>. The returned data will preserve the original order.
Upvotes: 27