Reputation: 607
How to remove the last element from an array in VB.NET. I need to split the street and housenumber.
STREET
NUMBER
My code:
'split address
Dim addressArray() As String = args.Content.Split(" ")
'remove last element and return the joined array
Return String.Join(" ", addressArray.Remove(addressArray.Length() - 1))
Upvotes: 5
Views: 19868
Reputation: 54532
You could also try using Redim Preserve. These statements are carry overs from the Visual Basic 6.0 days and are not considered the .NET way of doing things, but it is another option. There may be performance issues though according to this article.
Redim Preserve addressArray(addressArray.Length - 1)
Actually to delete the last item of array you would have to:
Redim Preserve addressArray(addressArray.Length - 2)
since they are zero based and the length is one based.
Upvotes: 6
Reputation: 700352
You can't remove items from an array. The size of an array is decided when you create it, and can't be changed.
You can create a result that contains the items from the array except the last one:
Return String.Join(" ", addressArray.Take(addressArray.Length() - 1))
If you are concerned about performance, you should not do any Split
or Join
at all, but simply get the parts of the string using simple string operations:
Dim pos As Integer = args.Content.LastIndexOf(" "C)
Dim street As String = args.Content.Substring(0, pos)
Dim number As String = args.Content.Substring(pos + 1)
This is at least ten times faster than any other method presented here.
Here is the performance test code (C#):
Dim time As Performance = New Performance(1000000, 6)
Dim address As String = "aölskdjf öawe öofij 42"
Console.WriteLine(time.Take("SplitTakeJoin", Sub()
Dim parts As String() = address.Split(" "c)
Dim street As String = String.Join(" ", parts.Take(parts.Length - 1))
End Sub))
Console.WriteLine(time.Take("SplitResizeJoin", Sub()
Dim parts As String() = address.Split(" "c)
Array.Resize(parts, parts.Length - 1)
Dim street As String = String.Join(" ", parts)
End Sub))
Console.WriteLine(time.Take("Substring", Sub()
Dim street As String = address.Substring(0, address.LastIndexOf(" "c))
End Sub))
Output:
SplitTakeJoin 0,000511 ms.
SplitResizeJoin 0,000323 ms.
Substring 0,000031 ms.
using this performance test class:
Public Class Performance
Private _iterations As Integer
Private _displayDigits As Integer
Private _emptyTime As TimeSpan
Public Sub New(ByVal iterations As Integer, ByVal displayDigits As Integer)
_iterations = iterations
_displayDigits = displayDigits
_emptyTime = TimeSpan.Zero
_emptyTime = Take(Sub()
End Sub)
End Sub
Private Function Take(ByVal action As Action) As TimeSpan
Dim w As Stopwatch = Stopwatch.StartNew()
For i As Integer = 0 To _iterations - 1 Step 10
Action()
Action()
Action()
Action()
Action()
Action()
Action()
Action()
Action()
Action()
Next
w.Stop()
Return w.Elapsed - _emptyTime
End Function
Public Function Take(ByVal title As String, ByVal action As Action) As String
Dim Time As TimeSpan = Take(action)
Return title + " " + (Time.TotalMilliseconds / Convert.ToDouble(_iterations)).ToString("N" + _displayDigits.ToString()) + " ms."
End Function
End Class
Upvotes: 5
Reputation: 11773
Dim foo() As String = "This is a test".Split(New Char() {" "c}, StringSplitOptions.RemoveEmptyEntries)
Array.Resize(foo, foo.Length - 1)
Dim s As String = String.Join(" ", foo)
or use lists
Dim foo As New List(Of String)
foo.AddRange("This is a test".Split(New Char() {" "c}, StringSplitOptions.RemoveEmptyEntries))
foo.RemoveAt(foo.Count - 1)
Dim s As String = String.Join(" ", foo)
As far as using LINQ and performance, judge for yourself
Public Class Form1
'to LINQ or not to LINQ
'judge for yourself
Dim stpw As New Stopwatch
Private Sub Button1_Click(sender As System.Object, _
e As System.EventArgs) Handles Button1.Click
Dim ipsumA() As String = New String() {"Lorem", "ipsum", "dolor", "sit", _
"amet", "consectetur", "adipisicing", _
"elit", "sed", "do", "eiusmod", _
"tempor", "incididunt", "ut", "labore", _
"et", "dolore", "magna", "aliqua", "Ut", _
"enim", "ad", "minim", "veniam", "quis", _
"nostrud", "exercitation", "ullamco", _
"laboris", "nisi", "ut", "aliquip", "ex", _
"ea", "commodo", "consequat", "Duis", "aute", _
"irure", "dolor", "in", "reprehenderit", "in", _
"voluptate", "velit", "esse", "cillum", "dolore", _
"eu", "fugiat", "nulla", "pariatur", "Excepteur", _
"sint", "occaecat", "cupidatat", "non", "proident", _
"sunt", "in", "culpa", "qui", "officia", "deserunt", _
"mollit", "anim", "id", "est", "laborum"}
Const tries As Integer = 100000
Debug.WriteLine("")
stpw.Reset()
stpw.Start()
For x As Integer = 1 To tries
Dim s As String = arrayTake(ipsumA)
Next
stpw.Stop()
Debug.WriteLine(stpw.ElapsedTicks.ToString)
stpw.Reset()
stpw.Start()
For x As Integer = 1 To tries
Dim s As String = arrayRsz(ipsumA)
Next
stpw.Stop()
Debug.WriteLine(stpw.ElapsedTicks.ToString)
End Sub
Private Function arrayRsz(test As String()) As String
Array.Resize(test, test.Length - 1)
Return String.Join(" ", test)
End Function
Private Function arrayTake(test As String()) As String
Return String.Join(" ", test.Take(test.Length - 1))
End Function
End Class
Upvotes: 7
Reputation: 9193
This will return all but the last "word/number" in a String as an array of Strings.
Return args.content.Split(" ").Take((args.content.Split(" ").Count - 1)).ToArray()
Upvotes: 1