# Thread: [RESOLVED] String of Numbers to Range of Numbers

1. ## [RESOLVED] String of Numbers to Range of Numbers

Hi, I am hoping someone can help with this or point me in the right direction. I have tried searching the site but could not find anything similar and didn't know exactly how to search this. So I apologize if this has been discussed/answered already.

I have a sub that will generate a string of numbers separated by a comma. I would like a function that will combine the numbers into ranges of numbers with a hyphen. Ex:

Generated from sub:
501-510, 1232, 1233, 1234, 367, 366, 365, 50-52, 893, 897, 1104

Function Output:
50-52, 365-367, 501-510, 893, 897, 1104, 1232-1234

The original numbers and combination (Generated from Sub) could be any amount of numbers and in any combination. The number will always be whole numbers and always positive. The function should put them in an order like the Function output numbers above.

I hope this makes sense, Thank you.

2. ## Re: String of Numbers to Range of Numbers

You can use stringVariable.Split() to convert the string into an array of strings (use "," as the separator).

One way would be to make a boolean array which has enough elements for all of the numbers (so for your example data, the array would have an upperbound of at least 1234).

Once you have that, read thru the items and set the boolean values in the array to True when a single value is found (so for 1232 set booleanArray(1232)=True ), and for ranges use a For loop to set the values to True.

When that is done you can loop the boolean array to find items that are set, and build the string accordingly. When you find a True in the array, that number should be part of the output - but if the next item is also true you need to display a range.

Of course it would be easier if the original sub generated the boolean array instead (or even better a List(Of Integer) ), but that might not be viable in your circumstances.

3. ## Re: String of Numbers to Range of Numbers

You can use stringVariable.Split() to convert the string into an array of strings (use "," as the separator). OK I understand and can do this.

One way would be to make a boolean array which has enough elements for all of the numbers (so for your example data, the array would have an upperbound of at least 1234). I have never worked with boolean arrays before. I understand the concept and what you are saying just wouldn't know how to initiate.

Once you have that, read thru the items and set the boolean values in the array to True when a single value is found (so for 1232 set booleanArray(1232)=True ), and for ranges use a For loop to set the values to True. Makes sense but again would not know how to initiate.

When that is done you can loop the boolean array to find items that are set, and build the string accordingly. When you find a True in the array, that number should be part of the output - but if the next item is also true you need to display a range. OK, I understand the concept and what you are saying but again..

Of course it would be easier if the original sub generated the boolean array instead (or even better a List(Of Integer) ), but that might not be viable in your circumstances. I could convert the string to List(of Integer) before sending to the function if that truly would make it easier. I do not believe that it will affect the sub in anyway.

4. ## Re: String of Numbers to Range of Numbers

Converting from strings to numbers is mandatory in order to build the output you want (without it, you wouldn't be able to get 365-367), it's just a matter of where that conversion happens.

After I posted I realised that just using a List(of Integer) would be best, as it simplifies the design and probably memory usage too.

When you have the source items Split, you can add them to the list - for a single number just add the number, if it is a range like 501-510 then use a For loop to add all the items in the range.

You can then sort the list, and build the output string you want based on the items in it. If the next number is one higher than the current number then they are both part of a range, otherwise the current number is just a single number (or the end of a range). Use appropriate variables to determine if you are currently in a range, and which number the range started with.

5. ## Re: String of Numbers to Range of Numbers

OK, so I got it working. I think I did it the way you explained. I took a two prong approach using two separate functions. If this could be simplified I would love to know how. The first function will get all the numbers like you suggested, split the ranges, and put them in acceding order.

The second function will then take the sorted numbers and place them back into a ranged format. I then, back in the sub, take the new list and join to a new string.

Get the Point Numbers, separate and place in order:
Code:
```    Public Function ToSortedListOfPointNumbers(ByVal pointNumbers As String)

Dim pointNumberList As New List(Of Integer)

For Each pointNumber As String In pointNumbers.Split(","c)

If pointNumber.Contains("-"c) Then

Dim firstNumber As Integer = Convert.ToInt32(pointNumber.Split("-"c)(0))

Dim lastNumber As Integer = Convert.ToInt32(pointNumber.Split("-"c)(1))

For pn As Integer = firstNumber To lastNumber

Next

Else

End If

Next

Dim sortedPointNumberList As List(Of Integer) = pointNumberList.OrderBy(Function(number) number).ToList()

Return sortedPointNumberList

End Function```
Take Sorted Point Numbers and place into ranged groups
Code:
```    Function ToRangesOfPointNumbers(ByVal sortedPointNumberList As List(Of Integer)) As String()

If sortedPointNumberList.Count < 1 Then Return New String() {}

Dim numberOfPoints = sortedPointNumberList.Count
Dim startNumbers = New List(Of Integer)()
Dim endNumbers = New List(Of Integer)()

For i = 0 To numberOfPoints - 1 - 1

If i = 0 Then startNumbers.Add(sortedPointNumberList(0))

If sortedPointNumberList(i + 1) > sortedPointNumberList(i) + 1 Then

End If

Next

Return Enumerable.Range(0, endNumbers.Count).[Select](Function(i) startNumbers(i).ToString() + (If(endNumbers(i) = startNumbers(i), "", "-" & endNumbers(i).ToString()))).ToArray()

End Function```
In sub to final result of updatedIncludedPointNumbers
Code:
```Dim sortedPointNumbers = ToSortedListOfPointNumbers(includedNumbers & "," & cogoPointsToAdd)

Dim rangedPointNumbers = ToRangesOfPointNumbers(sortedPointNumbers)

Dim updatedIncludedPointNumbers As String = String.Join(",", rangedPointNumbers.ToArray)```
What do you think? I feel this could be simplified, but I have tunnel vision now and cant seem to see it. I will play with it over the weekend but any pointers or suggestions are very welcome.

6. ## Re: [RESOLVED] String of Numbers to Range of Numbers

That looks good

In ToSortedListOfPointNumbers, I would change this section:
Code:
```                Dim firstNumber As Integer = Convert.ToInt32(pointNumber.Split("-"c)(0))

Dim lastNumber As Integer = Convert.ToInt32(pointNumber.Split("-"c)(1))

For pn As Integer = firstNumber To lastNumber```
...to:
Code:
```                Dim rangeNumbers As String = pointNumber.Split("-"c)

For pn As Integer = Convert.ToInt32(rangeNumbers(0)) To Convert.ToInt32(rangeNumbers(1))```
This should run slightly faster (as the complex split only happens once), and takes a little less code.

Note however that this section won't cope with negative numbers (due to the - character), so will need some extra work if you think you might ever need to deal with them.

In ToRangesOfPointNumbers I would change this:
Code:
```        For i = 0 To numberOfPoints - 1 - 1

If i = 0 Then startNumbers.Add(sortedPointNumberList(0))```
to:
Code:
```        startNumbers.Add(sortedPointNumberList(0))

For i = 0 To numberOfPoints - 1 - 1```
...because you have already checked that sortedPointNumberList contains at least one item.

There isn't really much scope to simplify these routines, but if you could modify the original sub the data comes from (so that it returns a List(of Integer)) then that would simplify the process as it would reduce ToSortedListOfPointNumbers to just the OrderBy line.

7. ## Re: [RESOLVED] String of Numbers to Range of Numbers

Thank so much! I got a little help from "the great white box of hope" (Google). Once you explained how to approach it, it was easier to search for what I was looking for. I will defiantly be incorporating your suggestions. And there should never be negative numbers as these represent survey point numbers which are always positive. So I should be good. (Famous last words)

Thank you again so much!!

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•

Featured