The combination of the following two methods should do what you want. The idea is that if the number of items is n then the number of subsets is 2^n. And if you iterate from 0 to 2^n - 1 and look at the numbers in binary you'll have one digit for each item and if the digit is 1 then you include the item, and if it is 0 you don't. I'm using BigInteger here as int would only work for a collection of less than 32 items and long would only work for less than 64.
public static IEnumerable<IEnumerable<T>> PowerSets<T>(this IList<T> set) { var totalSets = BigInteger.Pow(2, set.Count); for (BigInteger i = 0; i < totalSets; i++) { yield return set.SubSet(i); } } public static IEnumerable<T> SubSet<T>(this IList<T> set, BigInteger n) { for (int i = 0; i < set.Count && n > 0; i++) { if ((n & 1) == 1) { yield return set[i]; } n = n >> 1; } }
With that the following code
var states = new[] { "NJ", "AK", "NY" }; foreach (var subset in states.PowerSets()) { Console.WriteLine("[" + string.Join(",", subset.Select(s => "'" + s + "'")) + "]"); }
Will give you this output.
[] ['NJ'] ['AK'] ['NJ','AK'] ['NY'] ['NJ','NY'] ['AK','NY'] ['NJ','AK','NY']