Solved

Finding if Numbers are ranges

Posted on 2016-10-07
8
51 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
Comment
Question by:AlexPonnath
  • 4
  • 3
8 Comments
 
LVL 33

Expert Comment

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

Open in new window


Would you expect the output to be -
5125551122 - 5125551132
5125551140

Open in new window

Or
5125551122 - 5125551129
5125551130 - 5125551132
5125551140

Open in new window


-saige-
0
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 41834256
0
 

Author Comment

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

5125551122 - 5125551132
5125551140
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:AlexPonnath
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 33

Expert Comment

by:it_saige
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

Open in new window


Which produces the following output -Capture.JPG
-saige-
0
 
LVL 33

Expert Comment

by:it_saige
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

Open in new window

Produces the following output -Capture.JPG
-saige-
0
 

Author Comment

by:AlexPonnath
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 33

Accepted Solution

by:
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

Open in new window


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

Open in new window


Produces the following output -Capture.JPG
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

Open in new window

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

Open in new window


Produces the following output -Capture.JPG
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>

Open in new window

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

Open in new window

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

Open in new window


Produces the following output -Capture.JPG
-saige-
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

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

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

Join & Ask a Question