splitting a collection of numbers

  • Thread starter Thread starter djcamo
  • Start date Start date
D

djcamo

Hi,

I have a situation where I have a collection that holds numbers.
Mostly they are concurrent eg. 125801-125899 but sometimes they are
not eg. 125801-125899, 195301-399. Is there any way to split the
numbers and create another collection based on where the numbers
change, that is one colletion for the 125801-125899 range and another
for the 195301-399 range.

Any help much appreciated.

Cheers
David
 
You haven't said what type of collection your 'numbers' are in, or, for that
matter, what type of 'numbers' you are dealing with, so, so let's assume,
for the purpose of the exercise, that you are dealing with a generic-based
List(Of Integer).

I also assume that you mave miss-typed the second range and that it actually
should be 195301-195399.

So, if you sort your collection you end up with a list that looks like:

125801
125802
...
125898
125899
195301
195302
...
195398
195399

And you want to split the collection between 125899 and 195301 so that you
have two new collections.

If you know, in advance, how many new collections you will have then you can
declare the appropriate number of collections and then fill them
appropriately:

_existingcollection.Sort()

Dim _newcollection1 = New List(Of Integer)
Dim _newcollection2 = New List(Of Integer)

Dim _currentcollection = _newcollection1

_currentcollection.Add(_existingcollection(0))

For _i = 1 To _existingcollection.Count - 1
If _existingcollection(_i) <> _existingcollection(_i - 1) Then
_currentcollection = _newcollection2
_currentcollection.Add(_existingcollection(_i))
Next

When the 'range break' is encountered, the reference to the new collection
that is being used is changed.

The result is that _newcollection1 contains 1235801 to 135899 inclusive and
_newcollection2 contains 195301 to 195399 inclusive.

But .... you will run into problems if you do not know in advance how many
ranges you have.

To cater for this, a better mousetrap would be:

_existingcollection.Sort()

Dim _newcollections = New List(Of List Of(Integer))

Dim _newcollection = New List(Of Integer)

_newcollection.Add(_existingcollection(0))

For _i = 1 To _existingcollection.Count - 1
If _existingcollection(_i) <> _existingcollection(_i - 1) Then
_newcollections.Add(_newcollection)
_newcollection = New List(Of Integer)
End If
_newcollection.Add(_existingcollection(_i))
Next

_newcollections.Add(_newcollection)

This results in a collection of ranges with each range containing 1 or more
consectutive integers.

You can obtain the number of ranges with:

_newcollections.Count

You can obtain the actual ranges with:

For Each _range in _newcollections
Console.Writeline("{0} - {1}", _range(0), _range(_range.Count - 1))
Next

or:

For _i = 0 to _newcollections.Count - 1
Dim _range = _newcollections(_i)
Console.Writeline("Range {0} contains {1} - {2}", _i + 1, _range(0),
_range(_range.Count - 1))
Next

This type of thing can be easliy modified so that, instead of 'storing' with
lists of numbers, you have a collection of Range objects that each contain
information about the range, for example, it's first and last values.
 
Correction!

The test inside each of the loops demos=nstrated should read ...

If _existingcollection(_i) - 1 <> _existingcollection(_i - 1) Then ...
 
Correction!

The test inside each of the loops demos=nstrated should read ...

  If _existingcollection(_i) - 1 <>  _existingcollection(_i - 1) Then ....



















- Show quoted text -

Thank you for that, very much appreciated

David
 
Back
Top