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(c.Append)); 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.Append(i))); return combos; } #if NET452 /// Appends a value to the end of the sequence. /// A sequence of values. /// The value to append to . /// The type of the elements of . /// A new sequence that ends with . public static IEnumerable Append(this IEnumerable source, T element) { foreach (var src in source) yield return src; yield return element; } /// Prepends a value to the beginning of the sequence. /// A sequence of values. /// The value to prepend to . /// The type of the elements of . /// A new sequence that begins with . public static IEnumerable Prepend(this IEnumerable source, T element) { yield return element; foreach (var src in source) yield return src; } #endif } }