How to get all the unique n-long combinations of a set of duplicatable elements?

前端 未结 5 1946
难免孤独
难免孤独 2020-12-21 08:48

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

5条回答
  •  渐次进展
    2020-12-21 09:12

    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);
    

提交回复
热议问题