AlexPonnath
asked on
Finding if Numbers are ranges
I am having the need to determine if numbers read from a database are sequential, in my case its phone numbers
So i will pass the following numbers
5125551122
5125551130
5125551131
5125551132
5125551140
What i want to create as an output is something like that
5125551122
5125551130 - 5125551132
5125551140
So i will pass the following numbers
5125551122
5125551130
5125551131
5125551132
5125551140
What i want to create as an output is something like that
5125551122
5125551130 - 5125551132
5125551140
we call that Data Islands. Have a look at https://www.simple-talk.com/sql/t-sql-programming/the-sql-of-gaps-and-islands-in-sequences/ and http://sqlmag.com/sql-server-2012/solving-gaps-and-islands-enhanced-window-functions
ASKER
The below is what I would want to output
5125551122 - 5125551132
5125551140
5125551122 - 5125551132
5125551140
ASKER
The SQL Data Island is not an options since the Data comes from a text file and there is no SQL Server for this app
See if this doesn't do the trick for you:
Which produces the following output -
-saige-
Module Module1
Sub Main()
Dim phoneNumbers = New List(Of String) From {"5125551122", "5125551123", "5125551124", "5125551125", "5125551126", "5125551127", "5125551128", "5125551129", "5125551130", "5125551131", "5125551132", "5125551140"}
phoneNumbers = phoneNumbers.OrderBy(Function(x) x).ToList()
Dim results = String.Join(Environment.NewLine, phoneNumbers.GroupAdjacentBy(Function(x, y) (Convert.ToInt64(x) + 1).ToString(String.Format("D{0}", x.Length)) = y).Select(Function(g) New List(Of String)() From {g.First(), g.Last()}.Distinct()).Select(Function(g) String.Join(" - ", g)))
Console.WriteLine(results)
Console.ReadLine()
End Sub
End Module
Module Extensions
<System.Runtime.CompilerServices.Extension()> _
Public Iterator Function GroupAdjacentBy(Of T)(source As IEnumerable(Of T), predicate As Func(Of T, T, Boolean)) As IEnumerable(Of IEnumerable(Of T))
Using e = source.GetEnumerator()
If e.MoveNext() Then
Dim list = New List(Of T)() From {e.Current}
Dim pred = e.Current
While e.MoveNext()
If predicate(pred, e.Current) Then
list.Add(e.Current)
Else
Yield list
list = New List(Of T)() From {e.Current}
End If
pred = e.Current
End While
Yield list
End If
End Using
End Function
End Module
Which produces the following output -
-saige-
And just tested your original list of numbers:
-saige-
Module Module1
Sub Main()
Dim phoneNumbers = New List(Of String) From {"5125551122", "5125551130", "5125551131", "5125551132", "5125551140"}
phoneNumbers = phoneNumbers.OrderBy(Function(x) x).ToList()
Dim results = String.Join(Environment.NewLine, phoneNumbers.GroupAdjacentBy(Function(x, y) (Convert.ToInt64(x) + 1).ToString(String.Format("D{0}", x.Length)) = y).Select(Function(g) New List(Of String)() From {g.First(), g.Last()}.Distinct()).Select(Function(g) String.Join(" - ", g)))
Console.WriteLine(results)
Console.ReadLine()
End Sub
End Module
Module Extensions
<System.Runtime.CompilerServices.Extension()> _
Public Iterator Function GroupAdjacentBy(Of T)(source As IEnumerable(Of T), predicate As Func(Of T, T, Boolean)) As IEnumerable(Of IEnumerable(Of T))
Using e = source.GetEnumerator()
If e.MoveNext() Then
Dim list = New List(Of T)() From {e.Current}
Dim pred = e.Current
While e.MoveNext()
If predicate(pred, e.Current) Then
list.Add(e.Current)
Else
Yield list
list = New List(Of T)() From {e.Current}
End If
pred = e.Current
End While
Yield list
End If
End Using
End Function
End Module
Produces the following output --saige-
ASKER
Yes the console app does work, is there a way you can provide the code for a non console app like a function to which i can just pass one nbr after the other ? My code loops thru a List() which has the nbrs
and i want to be able to get the output as list which i can then loop thru
and i want to be able to get the output as list which i can then loop thru
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Open in new window
Would you expect the output to be -
Open in new window
OrOpen in new window
-saige-