This is the non-recursive C# version:
static void MakeUniqueRanges(List<AgeGroup> ranges)
{
for (int i = 0; i < ranges.Count - 1; i++)
{
AgeGroup first = ranges[i];
AgeGroup second = ranges[i + 1];
while (first.Higher > second.Lower)
{
//range is mixed..
AgeGroup newRange = new AgeGroup();
newRange.Lower = first.Lower;
newRange.Higher = second.Higher;
ranges.RemoveAt(i); //Remove "first"
ranges[i] = newRange; //Replace "second"
if (i == ranges.Count - 1) return; //Are we now at the end of the list?
first = ranges[i];
second = ranges[i + 1];
}
}
}
And this should be the VB equivalent:
Public Sub MakeUniqueRanges(ByVal ranges As List(Of AgeGroup))
Dim i as Integer = 0
While i <= ranges.Count - 2
Dim first As AgeGroup = ranges(i)
Dim second As AgeGroup = ranges(i + 1)
While first.Higher > second.Lower
'range is mixed..construct a new range by mixing the two ranges
Dim newRange As New AgeGroup()
newRange.Lower = first.Lower
newRange.Higher = second.Higher
ranges.RemoveAt(i) 'Remove "first"
ranges(i) = newRange
If i = ranges.Count - 1 Then Return
first = ranges(i)
second = ranges(i + 1)
End While
i = i + 1
End While
End Sub
So, why does your original attempt not work? Because in VB, the number of iterations to perform is fixed when you first start the loop. The end
value isn't reassessed each time through the loop. So this code:
Dim i = 5
For j = 0 To i
i = 1
Console.WriteLine("Hello")
Next
Prints Hello
6 times. Whereas in a C# for
loop, the termination condition is re-evaluated in full during each time through the loop.
See For...Next:
A
While...End While
Statement (Visual Basic) orDo...Loop
Statement (Visual Basic) works well when you don't know in advance how many times to run the statements in the loop. However, when you expect to run the loop a specific number of times, aFor...Next
loop is a better choice. You determine the number of iterations when you first enter the loop.
And the reason why the recursion is pointless? Because at any point where this function actually returns, it's already worked it's way along the entire list. What you shouldn't do, having invoked the function recursively, is then continue working through the list again.
And when you make the recursive call, you force it to start again at the start of the list, that your current invocation has already checked.