I have found many solutions giving a collection elements combined in all possible orders but they all use every element just once in every result while I need them to be tr
Eric Lippert has presented a general-purpose method of generating a cartesian product from any number of sequences which he blogs about here.
He wrote an extension method that looks like this:
public static class Combinations
{
public static IEnumerable> CartesianProduct(this IEnumerable> sequences)
{
IEnumerable> emptyProduct = new[] { Enumerable.Empty() };
return sequences.Aggregate(
emptyProduct,
(accumulator, sequence) =>
from accseq in accumulator
from item in sequence
select accseq.Concat(new[] { item }));
}
}
Given that extension method, the solution to the original problem can be done like this:
var items = new[] { "a", "b", "c" };
int numInEachSelection = 2;
var combs = Enumerable.Repeat(items, numInEachSelection).CartesianProduct();
foreach (var comb in combs)
Console.WriteLine(string.Join(", ", comb));
Note that combs is an IEnumerable - it is a sequence of enumerables each of which is a sequence representing one combination.
If you don't need a general-purpose method like that and you are happy to have each combination in a separate object with properties called Item1 and Item2 for the two combined items, the easiest way is this:
var items = new[] { "a", "b", "c" };
var combs = from Item1 in items from Item2 in items select new {Item1, Item2};
foreach (var comb in combs)
Console.WriteLine(comb);