using System.Collections.Generic; using System.Linq; namespace MLEM.Extensions { /// /// A set of extensions for dealing with collections of various kinds /// public static class CollectionExtensions { /// /// This method returns a set of possible combinations of n items from n different sets, where the order of the items in each combination is based on the order of the input sets. /// For a version of this method that returns indices rather than entries, see . /// /// Given the input set {{1, 2, 3}, {A, B}, {+, -}}, the returned set would contain the following sets: /// /// {1, A, +}, {1, A, -}, {1, B, +}, {1, B, -}, /// {2, A, +}, {2, A, -}, {2, B, +}, {2, B, -}, /// {3, A, +}, {3, A, -}, {3, B, +}, {3, B, -} /// /// /// /// The different sets to be combined /// The type of the items in the sets /// All combinations of set items as described public static IEnumerable> Combinations(this IEnumerable> things) { var combos = Enumerable.Repeat(Enumerable.Empty(), 1); foreach (var t in things) combos = combos.SelectMany(c => t.Select(o => c.Concat(Enumerable.Repeat(o, 1)))); return combos; } /// /// This method returns a set of possible combinations of n indices of items from n different sets, where the order of the items' indices in each combination is based on the order of the input sets. /// For a version of this method that returns entries rather than indices, see . /// /// Given the input set {{1, 2, 3}, {A, B}, {+, -}}, the returned set would contain the following sets: /// /// {0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, /// {1, 0, 0}, {1, 0, 1}, {1, 1, 0}, {1, 1, 1}, /// {2, 0, 0}, {2, 0, 1}, {2, 1, 0}, {2, 1, 1} /// /// /// /// The different sets to be combined /// The type of the items in the sets /// All combinations of set items as described public static IEnumerable> IndexCombinations(this IEnumerable> things) { var combos = Enumerable.Repeat(Enumerable.Empty(), 1); foreach (var t in things) combos = combos.SelectMany(c => t.Select((o, i) => c.Concat(Enumerable.Repeat(i, 1)))); return combos; } } }