I have 6 items which have to be combinated,
items listed: ( this is an example)
Want the input as strings? and no recursion? then here's the final solution, a simple adaptation of my previous sample:
Dim Lines As New List(Of List(Of String))
AddItem(Lines, "a ")
AddItem(Lines, "b ")
AddItem(Lines, "c1|c2|c3 ")
AddItem(Lines, "d ")
AddItem(Lines, "e1|e2")
AddItem(Lines, "f ") ' etc
Dim i As Integer
Dim j As Integer
Dim ItemnrInLine(Lines.Count - 1) As Integer
Dim NrCombinations = 1
For i = 0 To (Lines.Count - 1)
ItemnrInLine(i) = 0
NrCombinations *= Lines(i).Count
Next
ItemnrInLine(Lines.Count - 1) = -1 ' to get first combination as solution
For i = 1 To NrCombinations
ItemnrInLine(Lines.Count - 1) += 1
For j = Lines.Count - 1 To 0 Step -1
If ItemnrInLine(j) = Lines(j).Count Then
ItemnrInLine(j) = 0
ItemnrInLine(j - 1) += 1
End If
Next
printOut(Lines, ItemnrInLine)
Next
Sub printOut(ByVal Lines As List(Of List(Of String)), ByVal ItemnrInLine() As Integer)
Dim Result As String = ""
For k = 0 To Lines.Count - 1
Result = Result & Lines(k)(ItemnrInLine(k)).Trim & " "
Next
Debug.WriteLine(Result)
End Sub
Sub AddItem(ByVal Lines As List(Of List(Of String)), ByVal inputString As String)
Dim words() As String = inputString.Split("|"c)
Dim wordList As New List(Of String)
For i As Integer = 0 To words.Count - 1
wordList.Add(words(i))
Next
Lines.Add(wordList)
End Sub
Here's a recursive solution for VB 2010 (probably not very good performance-wise when there are a lot of combinations, but it's a start):
Function GetCombinations(items As String()(), Optional index As Integer = 0) As List(Of String())
Dim combinations As New List(Of String())
Dim lastIndex = items.Count - 1
Select Case index
Case Is < 0, Is > lastIndex
Throw New ArgumentException("index should be 0 or greater")
Case lastIndex
For Each item In items(index)
combinations.Add({item})
Next
Case Else
Dim nextCombinations = GetCombinations(items, index + 1)
For Each item In items(index)
For Each nextCombination In nextCombinations
combinations.Add({item}.Concat(nextCombination).ToArray)
Next
Next
End Select
Return combinations
End Function
Test code:
Dim items = {({"Ape"}), ({"Cow"}), ({"Deer", "Small deer", "Big deer"}), ({"Sheep"}), ({"Mouse", "Black Mouse", "White mouse"})}
For Each combination In GetCombinations(items)
Console.WriteLine(String.Join(", ", combination))
Next
Test outputs:
Ape, Cow, Deer, Sheep, Mouse
Ape, Cow, Deer, Sheep, Black Mouse
Ape, Cow, Deer, Sheep, White mouse
Ape, Cow, Small deer, Sheep, Mouse
Ape, Cow, Small deer, Sheep, Black Mouse
Ape, Cow, Small deer, Sheep, White mouse
Ape, Cow, Big deer, Sheep, Mouse
Ape, Cow, Big deer, Sheep, Black Mouse
Ape, Cow, Big deer, Sheep, White mouse
I can't comment on the approach @Martin supplied as I'm not a member of Experts Exchange, but here is how I would approach the problem.
You want an IEnumerable (of IEnumerable (of T))
When you have "Ape", you need to think of it as {Ape}. That makes your list:
{Ape}, {Cow}, {Deer, Small deer, Big deer}, {sheep}
From there, you build your combinations by grouping the outer list and iterating through the inner list(s).
I.E. The first item {Ape} only has one element, so you would only iterate on that once. The same with {Cow}, but the third with all the deer would be iterated over 3 times.
That should be enough to get you started.
You will need a variant of my solution, that I presented in HERE in this solution for a similar problem. maybe it suffices to get you along?
Perhaps you're not allowed to see the answer, so I copy it here. Someone wanted all combinations of 1 and 2 in series with length 3
Dim HighestValue As Integer = 2 ' max value
Dim NrOfValues As Integer = 3 ' nr of values in one result
Dim Values(NrOfValues) As Integer
Dim i As Integer
For i = 0 To NrOfValues - 1
Values(i) = 1
Next
Values(NrOfValues - 1) = 0 ' to generate first as ALL 1
For i = 1 To HighestValue ^ NrOfValues
Values(NrOfValues - 1) += 1
For j As Integer = NrOfValues - 1 To 0 Step -1
If Values(j) > HighestValue Then
Values(j) = 1
Values(j - 1) += 1
End If
Next
Dim Result As String = ""
For j As Integer = 0 To NrOfValues - 1
Result = Result & CStr(Values(j))
Next
Debug.WriteLine(Result)
Next
You will need to put arrayvalues indexed by 1, 2, etc instead of the numbers itself, and invent a similar operation for each sublist.