Я бы предложил такой способ:
F # (тест-кейс)
let list1 = [ 1 .. 10 ]
let listEven, listOdd = List.partition (fun elem -> elem % 2 = 0) list1
printfn "Evens: %A\nOdds: %A" listEven listOdd
/* Result:
Evens: [2; 4; 6; 8; 10]
Odds: [1; 3; 5; 7; 9]
*/
C # (тест-кейс)
var list1 = Enumerable.Range(1, 10);
var (listEven, listOdd) = list1
.GroupBy(key => key % 2 == 0)
.Aggregate(
(part1: Enumerable.Empty<int>(), part2: Enumerable.Empty<int>()),
(accumulator, value) => {
if (value.Key)
{
accumulator.part1 = value.ToArray();
}
else
{
accumulator.part2 = value.ToArray();
}
return accumulator;
});
Console.WriteLine($"Evens: [{string.Join("; ", listEven)}]\nOdds: [{string.Join("; ", listOdd)}]");
/* Result:
Evens: [2; 4; 6; 8; 10]
Odds: [1; 3; 5; 7; 9]
*/
Для повторного использования и обобщения этого метода определите метод extension:
public static class EnumerableExtensions
{
public static (T[] part1, T[] part2) Partition<T>(this IEnumerable<T> self, Func<T, bool> predicate)
{
return self
.GroupBy(predicate)
.Aggregate(
(part1: Array.Empty<T>(), part2: Array.Empty<T>()),
(accumulator, value) => {
if (value.Key)
{
accumulator.part1 = value.ToArray();
}
else
{
accumulator.part2 = value.ToArray();
}
return accumulator;
});
}
}
Используйте его следующим образом:
var list1 = Enumerable.Range(1, 10);
var (listEven, listOdd) = list1.Partition(v => v % 2 == 0);
Console.WriteLine($"Evens: [{string.Join("; ", listEven)}]\nOdds: [{string.Join("; ", listOdd)}]");
/* Result:
Evens: [2; 4; 6; 8; 10]
Odds: [1; 3; 5; 7; 9]
*/
var str = "aAbbBcCddD";
var (lowers, uppers) = str.Partition(v => char.IsLower(v));
Console.WriteLine($"Lowers: [{string.Join("; ", lowers)}]\nUppers: [{string.Join("; ", uppers)}]");
/* Result:
Lowers: [a; b; b; c; d; d]
Uppers: [A; B; C; D]
*/