Reputation: 1665
I have 3 (Edit) mutually exclusive IEnumerables that I want to iterate over. I want to do something like this:
IEnumerable<Car> redCars = GetRedCars();
IEnumerable<Car> greenCars = GetGreenCars();
IEnumerable<Car> blueCars = GetBlueCars();
foreach(Car c in (redCars + greenCars + blueCars)) {
c.DoSomething();
}
...
The best way I can think of is:
...
List<Car> allCars = new List();
allCars.AddRange(redCars);
allCars.AddRange(greenCars);
allCars.AddRange(blueCars);
foreach(car in allCars) {
...
}
...
Is there a more concise way to do this? Seems like combinding IEnumberables should be trivial.
Upvotes: 8
Views: 1478
Reputation: 660058
As noted in other answers, Union does extra work to eliminate duplicates, Concat simply concatenates the sequences. However, as I noted in a comment above, there are performance costs to deeply nested concats. You might consider also using a SelectMany to flatten a bunch of iterators:
var carLists = new[]{GetRedCars(), GetGreenCars(), GetBlueCars()};
var allCars = from carList in carLists
from car in carList
select car;
foreach(var c in allCars) { ... }
You might find that to be more flexible should you discover that you actually have way more than three lists to iterate.
Upvotes: 3
Reputation: 1331
Is there a reason you need to do it in one loop? If so, the second way is probably the best. There's nothing that will work like the first way.
Unless there's an overriding need to do it in one loop, I'd do it in three loops which would be more time efficient.
Upvotes: 0
Reputation: 1062780
With LINQ:
foreach(car in redCars.Concat(greenCars).Concat(blueCars)) {
//...
}
For info, the difference here between Union
and Concat
is that Union
will do extra work to guarantee uniqueness; so if you don't expect duplicates (or alternatively: don't mind them) then Concat
is faster.
Upvotes: 20
Reputation: 23770
Use LINQ Union method.
foreach(Car c in redCars.Union(greenCars).Union(blueCars))
{
c.DoSomething();
}
Upvotes: 0