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
}
}