Generate combinations of elements held in multiple list of strings in C#

Just do a cross-join with each successive list:

 IEnumerable<string> lstRes = new List<string> {null};
 foreach(var list in lstMaster)
 {
     // cross join the current result with each member of the next list
     lstRes = lstRes.SelectMany(o => list.Select(s => o + s));
 }

results:

List<String> (8 items)
------------------------ 
1-Jan-2014 
1-Jan-2015 
1-Feb-2014 
1-Feb-2015 
2-Jan-2014 
2-Jan-2015 
2-Feb-2014 
2-Feb-2015 

Notes:

  • Declaring lstRes as an IEnumerable<string> prevents the unnecessary creation of additional lists that will be thrown away with each iteration

  • The instinctual null is used so that the first cross-join will have something to build on (with strings, null + s = s)


To make this truly dynamic you need two arrays of int loop variables (index and count):

int numLoops = lstMaster.Count;
int[] loopIndex = new int[numLoops];
int[] loopCnt = new int[numLoops];

Then you need the logic to iterate through all these loopIndexes.

Init to start value (optional)

for(int i = 0; i < numLoops; i++) loopIndex[i] = 0;
for(int i = 0; i < numLoops; i++) loopCnt[i] = lstMaster[i].Count;

Finally a big loop that works through all combinations.

bool finished = false;
while(!finished)
{
     // access current element
     string line = "";
     for(int i = 0; i < numLoops; i++)
     {
         line += lstMaster[i][loopIndex[i]];
     }
     llstRes.Add(line);
     int n = numLoops-1;                  
     for(;;)
     {
         // increment innermost loop
         loopIndex[n]++;
         // if at Cnt: reset, increment outer loop
         if(loopIndex[n] < loopCnt[n]) break;

         loopIndex[n] = 0;
         n--;
         if(n < 0)
         { 
             finished=true;
             break;
         }
     }       
}

Tags:

C#

.Net