Link to home
Start Free TrialLog in
Avatar of AlexPonnath
AlexPonnathFlag for United States of America

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
Avatar of it_saige
it_saige
Flag of United States of America image

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-
Avatar of AlexPonnath

ASKER

The below is what I would want to output

5125551122 - 5125551132
5125551140
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:
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 -User generated image
-saige-
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 -User generated image
-saige-
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
ASKER CERTIFIED SOLUTION
Avatar of it_saige
it_saige
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial