Sort
Elements, one after another, proceed in order. But often collections are not in an order we want. With the VB.NET Sort
subroutine we order elements by their values.
We sort collections in-place. Sorting is by default in ascending order: elements go from lowest to highest. We can implement a descending order.
First, we can use Array.Sort
on array instances. Here the array is of type String()
and it contains 3 strings (vegetables). Array.Sort
is called.
For-Each
loop, and finally we print results.Module Module1 Sub Main() ' Create an array of String() with 3 elements. Dim vegetables As String() = New String() {"turnip", "onion", "corn"} ' Use the System.Array.Sort shared method. System.Array.Sort(vegetables) ' Loop through the results and print them with Console.WriteLine. For Each value As String In vegetables Console.WriteLine(value) Next End Sub End Modulecorn onion turnip
Sort
, Reverse
Another way to reorder an array combines the Sort
and Reverse
methods. Effectively, this will give you a reverse alphabetical sort on strings.
Reverse
after Sort
, because Sort
will always produce an alphabetical array in this context.Module Module1 Sub Main() ' Create a String array with 5 elements. Dim array As String() = New String() {"X", _ "B", _ "A", _ "Z", _ "C"} ' Use the System.Array.Sort shared method. System.Array.Sort(Of String)(array) ' Invoke the Reverse method after sorting. System.Array.Reverse(array) ' Loop through the results. For Each value As String In array Console.WriteLine(value) Next End Sub End ModuleZ X C B A
Sort
, descendingHere is a better way to sort descending (from last to first) in VB.NET. No separate reverse call is needed. Instead, we use a special Comparison
Function.
DescendingComparison
, we create a descending sort by changing the order of the variables in the CompareTo
call.AddressOf
to reference our special Comparison
Function. Then we use For-Each
to display the result.Module Module1 Function DescendingComparison(ByVal valueA As String, ByVal valueB As String) As Integer ' Invert the order of the comparison to sort in descending order. Return valueB.CompareTo(valueA) End Function Sub Main() Dim letters As String() = {"X", "B", "A", "Z", "C"} ' Use custom DescendingComparison to sort in reverse. Array.Sort(Of String)(letters, New Comparison(Of String)(AddressOf DescendingComparison)) ' Display results. For Each value As String In letters Console.WriteLine("DESCENDING: {0}", value) Next End Sub End ModuleDESCENDING: Z DESCENDING: X DESCENDING: C DESCENDING: B DESCENDING: A
List
Sorting a List
is also easy. No custom algorithms need to be implemented. Instead, you can invoke the instance Sort
method on the List
you created.
System.Array.Sort
method so performance is similar.Module Module1 Sub Main() ' Create a List of Strings and add 4 Strings to it. Dim list As New List(Of String) list.Add("chair") list.Add("table") list.Add("desk") list.Add("couch") ' Use Sort method. list.Sort() ' Loop through the results and display them. For Each value As String In list Console.WriteLine(value) Next End Sub End Modulechair couch desk table
List
, sort with lambdaWith a List
, we can use a lambda expression to define the Comparison
Function. This may make the VB.NET code shorter and easier to read.
List
of 3 integers, and then Sort
it in descending (high to low) order, using a lambda expression.Module Module1 Sub Main() Dim numbers = New List(Of Integer)({20, 30, 40}) ' Use lambda to sort list in descending order. numbers.Sort(Function(valueA, valueB) valueB.CompareTo(valueA)) For Each number As Integer In numbers Console.WriteLine("LAMBDA SORTED NUMBER: {0}", number) Next End Sub End ModuleLAMBDA SORTED NUMBER: 40 LAMBDA SORTED NUMBER: 30 LAMBDA SORTED NUMBER: 20
Array.Sort()
operates on the original data. So we must make a copy of the original array if we wish to keep it in that order. We apply the Array.Copy
Function.
Module Module1 Sub Main() Dim names() As String = {"Zach", "Andrew", "David"} ' Create a copy of names array and sort it. Dim namesCopy(2) As String Array.Copy(names, namesCopy, 3) Array.Sort(namesCopy) ' Display arrays. Console.WriteLine(String.Join(",", names)) Console.WriteLine(String.Join(",", namesCopy)) End Sub End ModuleZach,Andrew,David Andrew,David,Zach
Sort
on 2 itemsSupport we have a List
of Tuples, and we want to sort based on the first value of each tuple, and then the second value. Here we use an ascending and also descending sort.
ComparisonTwoTuples
receives 2 tuples and returns an Integer. We call CompareTo
—if the first comparison is 0, we use a second comparison.Module Module1 Function GetData() As List(Of Tuple(Of Integer, Integer)) Dim result As New List(Of Tuple(Of Integer, Integer)) result.Add(New Tuple(Of Integer, Integer)(100, 1)) result.Add(New Tuple(Of Integer, Integer)(100, 2)) result.Add(New Tuple(Of Integer, Integer)(10, 2)) result.Add(New Tuple(Of Integer, Integer)(10, 1)) Return result End Function Function ComparisonTwoTuples(ByVal tupleA As Tuple(Of Integer, Integer), ByVal tupleB As Tuple(Of Integer, Integer)) As Integer ' Compare the first Item of each tuple in ascending order. Dim part1 As Integer = tupleA.Item1 Dim part2 As Integer = tupleB.Item1 Dim compareResult As Integer = part1.CompareTo(part2) ' If not equal, return the comparison result. If compareResult <> 0 Then Return compareResult End If ' Compare the second item of each tuple in descending order. Return tupleB.Item2.CompareTo(tupleA.Item2) End Function Sub Main() Dim data As List(Of Tuple(Of Integer, Integer)) = GetData() data.Sort(New Comparison(Of Tuple(Of Integer, Integer))(AddressOf ComparisonTwoTuples)) For Each value In data Console.WriteLine("SORTED ON 2 VALUES: {0}", value) Next End Sub End ModuleSORTED ON 2 VALUES: (10, 2) SORTED ON 2 VALUES: (10, 1) SORTED ON 2 VALUES: (100, 2) SORTED ON 2 VALUES: (100, 1)
SortedSet
Sort()
is sometimes a slow part of a program. There is a way to avoid calling Sort
: we can keep the data sorted as we go along. Consider SortedSet
.
List
, add 3 elements to it, and then call Sort
. The List
is sorted in-place.SortedSet
, and when we call Add()
, each item is stored in a sorted order—we never need to call Sort
.SortedSet
. Avoiding Sort
altogether seems to be a consistent performance boost.Module Module1 Sub Main() Dim m As Integer = 100000 Dim s1 As Stopwatch = Stopwatch.StartNew ' Version 1: add 3 strings to List, then Sort it. For i As Integer = 0 To m - 1 Dim list = New List(Of String) list.Add("zebra") list.Add("20") list.Add("bird") list.Sort() If list.Count <> 3 Then Return End If Next s1.Stop() Dim s2 As Stopwatch = Stopwatch.StartNew ' Version 2: add 3 strings to SortedSet. For i As Integer = 0 To m - 1 Dim sorted = New SortedSet(Of String) sorted.Add("zebra") sorted.Add("20") sorted.Add("bird") If sorted.Count <> 3 Then Return End If Next s2.Stop() Dim u As Integer = 1000000 Console.WriteLine(((s1.Elapsed.TotalMilliseconds * u) / m).ToString("0.00 ns")) Console.WriteLine(((s2.Elapsed.TotalMilliseconds * u) / m).ToString("0.00 ns")) End Sub End Module405.52 ns List, Sort 357.17 ns SortedSet
Sorting strings can be done in many ways. Here we examined ways to sort strings in alphabetical order, and also reverse alphabetical order. Built-in functions are well-tested.