Solved

# Finding if Numbers are ranges

Posted on 2016-10-07
30 Views
Last Modified: 2016-10-10
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
0
Question by:AlexPonnath
• 4
• 3
8 Comments

LVL 32

Expert Comment

ID: 41834195
What determines the grouping?  Consider the following:
``````5125551122
5125551123
5125551124
5125551125
5125551126
5125551127
5125551128
5125551129
5125551130
5125551131
5125551132
5125551140
``````

Would you expect the output to be -
``````5125551122 - 5125551132
5125551140
``````
Or
``````5125551122 - 5125551129
5125551130 - 5125551132
5125551140
``````

-saige-
0

LVL 69

Expert Comment

ID: 41834256
0

Author Comment

ID: 41834270
The below is what I would want to output

5125551122 - 5125551132
5125551140
0

Author Comment

ID: 41834407
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
0

LVL 32

Expert Comment

ID: 41834465
See if this doesn't do the trick for you:
``````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-
0

LVL 32

Expert Comment

ID: 41834468
And just tested your original list of numbers:
``````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-
0

Author Comment

ID: 41834498
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
0

LVL 32

Accepted Solution

it_saige earned 500 total points
ID: 41837036
The example provided is not specific to any implementation and therefore can be used for any vb.net project.  If you need a method that performs the task then here you go:
``````Module Extensions
<System.Runtime.CompilerServices.Extension()> _
Public Function PhoneGroups(source As IEnumerable(Of String)) As IEnumerable(Of String)
Return source.OrderBy(Function(x) x).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))
End Function

<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
``````

Example usage:

Console Implementation -
``````Module Module1
Sub Main()
Dim phoneNumbers = New List(Of String) From {"5125551122", "5125551130", "5125551131", "5125551132", "5125551140"}
For Each group In phoneNumbers.PhoneGroups()
Console.WriteLine(group)
Next
Console.ReadLine()
End Sub
End Module

Module Extensions
<System.Runtime.CompilerServices.Extension()> _
Public Function PhoneGroups(source As IEnumerable(Of String)) As IEnumerable(Of String)
Return source.OrderBy(Function(x) x).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))
End Function

<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 -
Windows Forms implementation -

Form1.vb -
``````Public Class Form1
ReadOnly phoneNumbers As New List(Of String) From {"5125551122", "5125551130", "5125551131", "5125551132", "5125551140"}

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ListBox1.DataSource = phoneNumbers.PhoneGroups().ToList()
End Sub
End Class

Module Extensions
<System.Runtime.CompilerServices.Extension()> _
Public Function PhoneGroups(source As IEnumerable(Of String)) As IEnumerable(Of String)
Return source.OrderBy(Function(x) x).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))
End Function

<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
``````
Form1.Designer.vb -
``````<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
Inherits System.Windows.Forms.Form

'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.ListBox1 = New System.Windows.Forms.ListBox()
Me.SuspendLayout()
'
'ListBox1
'
Me.ListBox1.FormattingEnabled = True
Me.ListBox1.Location = New System.Drawing.Point(13, 13)
Me.ListBox1.Name = "ListBox1"
Me.ListBox1.Size = New System.Drawing.Size(259, 95)
Me.ListBox1.TabIndex = 0
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(284, 123)
Me.Controls.Add(Me.ListBox1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)

End Sub
Friend WithEvents ListBox1 As System.Windows.Forms.ListBox

End Class
``````

Produces the following output -
ASP.NET implementation -

Default.aspx -
``````<%@ Page Title="Home Page" Language="VB" AutoEventWireup="true" CodeBehind="Default.aspx.vb" Inherits="EE_Q28975079_ASP._Default" %>
<form id="form1" runat="server">
<asp:ListBox ID="ListBox1" runat="server" Height="99px" Width="250px"></asp:ListBox>
</form>
``````
Default.aspx.vb -
``````Public Class _Default
Inherits Page
ReadOnly phoneNumbers As New List(Of String) From {"5125551122", "5125551130", "5125551131", "5125551132", "5125551140"}

Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
ListBox1.DataSource = phoneNumbers.PhoneGroups().ToList()
ListBox1.DataBind()
End Sub
End Class

Module Extensions
<System.Runtime.CompilerServices.Extension()> _
Public Function PhoneGroups(source As IEnumerable(Of String)) As IEnumerable(Of String)
Return source.OrderBy(Function(x) x).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))
End Function

<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
``````
Default.aspx.designer.vb -
``````'------------------------------------------------------------------------------
' <auto-generated>
'     This code was generated by a tool.
'
'     Changes to this file may cause incorrect behavior and will be lost if
'     the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------

Option Strict On
Option Explicit On

Partial Public Class _Default

'''<summary>
'''form1 control.
'''</summary>
'''<remarks>
'''Auto-generated field.
'''To modify move field declaration from designer file to code-behind file.
'''</remarks>
Protected WithEvents form1 As Global.System.Web.UI.HtmlControls.HtmlForm

'''<summary>
'''ListBox1 control.
'''</summary>
'''<remarks>
'''Auto-generated field.
'''To modify move field declaration from designer file to code-behind file.
'''</remarks>
Protected WithEvents ListBox1 As Global.System.Web.UI.WebControls.ListBox
End Class
``````

Produces the following output -
-saige-
0

## Join & Write a Comment Already a member? Login.

XML Literals are a great way to handle XML files and the community doesn’t use it as much as it should.  An XML Literal is like a String (http://msdn.microsoft.com/en-us/library/system.string.aspx) Literal, only instead of starting and ending with w…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
This tutorial demonstrates a quick way of adding group price to multiple Magento products.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

#### 705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

#### Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!