I've the following code:
var e = someList.GetEnumerator();
var a = new List<Foo>();
var b = new List<Foo>();
while(e.MoveNext()) {
if(CheckCondition(e.Current)) {
b.Add(e.Current);
break;
}
a.Add(e.Current);
}
while(e.MoveNext())
b.Add(e.Current)
This looks ugly. Basically, iterate through a list and add elements to one list until some condition kicks in, and add the rest to another list.
Is there a better way e.g. using linq ? CheckCondition() is expensive, and the lists can be huge so I'd prefer to not do anything that iterates the lists twice.
Here's a solution that's going to enumerate the list twice, but it won't check the condition the second time, so it should be faster:
var a = someList.TakeWhile(x => !CheckCondition(x)).ToList();
var b = someList.Skip(a.Count).ToList();
If someList
implements IList<T>
, each item will actually be enumerated only once, so there won't be any penalty.
I thought Skip
was optimized for the case of IList<T>
, but apparently it's not... However you could easily implement your own Skip
method that uses this optimization (see Jon Skeet's article about this)
It would actually be more elegant if there was a TakeUntil
method... we can easily create it:
public static IEnumerable<TSource> TakeUntil<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
foreach(var item in source)
{
if (predicate(item))
break;
yield return item;
}
}
With this method, the code becomes:
var a = someList.TakeUntil(CheckCondition).ToList();
var b = someList.Skip(a.Count).ToList();
I didn't want to change Ani's answer, but here's a slight simplification.
var listToBeAdded = a;
foreach (var item in someList)
{
if (listToBeAdded == a && CheckCondition(item))
listToBeAdded = b;
listToBeAdded.Add(item);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With