Joseph L. answered 05/03/26
Coding, Game Dev, AI and Tech Solutions Professional
I think recursion can get a bit confusing but the main thing here is knowing how to use Select and SelectMany:
public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> source, int size)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (size < 0) throw new ArgumentOutOfRangeException(nameof(size), "Size must be non-negative.");
if (size == 0) return new[] { Enumerable.Empty<T>() };
return source.SelectMany((element, index) =>
source.Skip(index + 1)
.Combinations(size - 1)
.Select(smallerCombination => new[] { element }.Concat(smallerCombination)));
}
Usage:
var numbers = new[] { 1, 2, 3, 7, 8, 9 };
foreach (var combination in numbers.Combinations(3))
Console.WriteLine("(" + string.Join(", ", combination) + ")");
However, if your are index visited tracking and just looping you can avoid a bunch of allocations for so you might be better off avoiding LINQ if things get really large.