Using LINQ, how do you partition an IEnumerable
in a way equivalent to F#'s List.parition function? The result should be the source sequence partitioned into two sequences based the predicate, with the predicate evaluated once per source item.
Enumerable.ToLookup
comes close.
var l = new int[]{1,2,3,4,5};
var split = l.ToLookup( i => i > 2);
var a = split[true]; // 3,4,5
var b = split[false]; // 1,2
It's not too hard to wrap this in a function.
public static (IEnumerable<TSource> Yeses, IEnumerable<TSource> Nos) Partition<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
//Null handling?
var s = source.ToLookup(i => predicate(i));
return (s[true], s[false]);
}
public static void Main(string[] args)
{
var l = new int[] { 1,2,3,4,5 };
var s = Partition(l, i => { Console.WriteLine($"Called: {i}"); return i > 2;});
Console.WriteLine(string.Join(",", s.Yeses));
Console.WriteLine(string.Join(",", s.Nos));
}
Called: 1
Called: 2
Called: 3
Called: 4
Called: 5
3,4,5
1,2