(I think) I needed the exact same thing, but I couldn't quite find exactly what I needed amongst the answers (mainly because they were in languages I don't know, I guess).
I came with this (The function itself):
Public Function nChooseK(Of T)(ByVal Values As List(Of T), ByVal k As Integer, Optional ByRef Result As List(Of List(Of T)) = Nothing, Optional ByRef CurCombination As List(Of T) = Nothing, Optional ByVal Offset As Integer = 0) As List(Of List(Of T))
Dim n = Values.Count
If CurCombination Is Nothing Then CurCombination = New List(Of T)
If Result Is Nothing Then Result = New List(Of List(Of T))
If k <= 0 Then
Result.Add(CurCombination.ToArray.ToList)
Return Result
Else
For i = Offset To n - k
CurCombination.Add(Values(i))
nChooseK(Values, k - 1, Result, CurCombination, i + 1)
CurCombination.RemoveAt(CurCombination.Count - 1)
Next
Return Result
End If
End Function
All one needs to do is put it in a module (or just above/below the sub/function which calls it I guess) and call it with any kind of variable and a number
How to call it:
nChooseK(List, kInteger)
Small example:
Dim NumbersCombinations As List(Of List(Of Integer)) = nChooseK(lstNumbers, k)
Full example for use with Integers and Strings along with printing the result to the screen:
Dim Numbers() As Integer = {1, 2, 3, 4, 5}
Dim lstNumbers = New List(Of Integer)
Dim k = 3
lstNumbers.AddRange(Numbers)
Dim NumbersCombinations As List(Of List(Of Integer)) = nChooseK(lstNumbers, k)
Dim sbCombinations1 As New StringBuilder
For i = 0 To NumbersCombinations.Count - 1
sbCombinations1.AppendLine()
For j = 0 To NumbersCombinations(i).Count - 1
sbCombinations1.Append(NumbersCombinations(i)(j) & " ")
Next
sbCombinations1.Length = sbCombinations1.Length - 1
Next
MsgBox(sbCombinations1.ToString)
Dim lstNoumera = New List(Of String)
lstNoumera.AddRange({"ena", "dio", "tria", "tessera", "pente"})
Dim Combinations As List(Of List(Of String)) = nChooseK(lstNoumera, k)
Dim sbCombinations2 As New StringBuilder
For i = 0 To Combinations.Count - 1
sbCombinations2.AppendLine()
For j = 0 To Combinations(i).Count - 1
sbCombinations2.Append(Combinations(i)(j) & " ")
Next
sbCombinations2.Length = sbCombinations2.Length - 1
Next
MsgBox(sbCombinations2.ToString)