It is more easy to get all combinations from one array than two arrays. And as we see, you need to store indices and array names along with the value of the elements in collections. So, in my opinion the best option is to combine these two arrays in one dictionary, where the key will be the value of the numbers and the value will be [ArrayName + Index of item] (f.e width0, height1 and so on....)
So, let's combine these arrays in one dictionary:
int[] width = new int[2] { 10, 20 };
int[] height = new int[2] { 30, 40 };
var widthDictionary = width.ToList().Select((number, index) => new { index, number })
.ToDictionary(key => key.number, value => string.Format("width{0}", value.index));
var heightDictionary = height.ToList().Select((number, index) => new { index, number })
.ToDictionary(key => key.number, value => string.Format("height{0}", value.index));
// And here is the final dictionary
var totalDictionary = widthDictionary.Union(heightDictionary);
Then add this method to your class: (source)
public static IEnumerable<IEnumerable<T>> GetPowerSet<T>(List<T> list)
{
return from m in Enumerable.Range(0, 1 << list.Count)
select
from i in Enumerable.Range(0, list.Count)
where (m & (1 << i)) != 0
select list[i];
}
Then send your dictionary as an argument to this method and project this collection as you want with the help of the Select()
method:
var sumOfCombinations = GetPowerSet(totalDictionary.ToList())
.Where(x => x.Count() > 0)
.Select(x => new
{
Numbers = x.Select(pair => pair.Key).ToList(),
DisplayValues = x.Select(pair => pair.Value).ToList()
})
.ToList();
And at the end you can display expected result as this:
sumOfCombinations.ForEach(x =>
{
x.Numbers.ForEach(number => Console.Write("{0} ", number));
x.DisplayValues.ForEach(displayValue => Console.Write("{0} ", displayValue));
Console.WriteLine();
});
And, the result is:
