Here is an implementation that uses as state a BigInteger
instead of a bool[]
or a BitArray
:
using System.Numerics;
public static IEnumerable<(T[], T[])> GetCollectionPairs<T>(T[] source)
{
BigInteger combinations = BigInteger.One << source.Length;
for (BigInteger i = 0; i < combinations; i++)
{
yield return
(
Enumerable.Range(0, source.Length)
.Where(j => (i & (BigInteger.One << j)) != 0)
.Select(j => source[j])
.ToArray(),
Enumerable.Range(0, source.Length)
.Where(j => (i & (BigInteger.One << j)) == 0)
.Select(j => source[j])
.ToArray()
);
}
}
Usage example:
var items = new string[] { "A", "B", "C", "D" };
var pairs = GetCollectionPairs(items);
foreach (var pair in pairs)
{
Console.WriteLine(
$"({String.Join("", pair.Item1)};{String.Join("", pair.Item2)})");
}
Output:
(;ABCD)
(A;BCD)
(B;ACD)
(AB;CD)
(C;ABD)
(AC;BD)
(BC;AD)
(ABC;D)
(D;ABC)
(AD;BC)
(BD;AC)
(ABD;C)
(CD;AB)
(ACD;B)
(BCD;A)
(ABCD;)
This generates (AB;CD) and (CD;AB) as different pairs. If this is not desirable, then simply loop until i < combinations / 2
instead of i < combinations
.