Solved

Finding if Numbers are ranges

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

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 69

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
 

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
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 32

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 32

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 32

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

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Article by: jpaulino
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.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now