How can I remove an element from an array in VB.NET?

How can I remove an element from an array in VB.NET ?

+26
source share
11 answers

As Heinzi said, the array has a fixed size. To โ€œdelete an elementโ€ or โ€œresizeโ€, you will need to create a new array with the desired size and copy the elements you need.

Here is the code to remove an element from the array:

<System.Runtime.CompilerServices.Extension()> _ Function RemoveAt(Of T)(ByVal arr As T(), ByVal index As Integer) As T() Dim uBound = arr.GetUpperBound(0) Dim lBound = arr.GetLowerBound(0) Dim arrLen = uBound - lBound If index < lBound OrElse index > uBound Then Throw New ArgumentOutOfRangeException( _ String.Format("Index must be from {0} to {1}.", lBound, uBound)) Else 'create an array 1 element less than the input array Dim outArr(arrLen - 1) As T 'copy the first part of the input array Array.Copy(arr, 0, outArr, 0, index) 'then copy the second part of the input array Array.Copy(arr, index + 1, outArr, index, uBound - index) Return outArr End If End Function 

You can use it as such:

 Module Module1 Sub Main() Dim arr = New String() {"abc", "mno", "xyz"} arr.RemoveAt(1) End Sub End Module 

In the above code, the second element ( "mno" ) [which has index 1] is removed from the array.

To use the extension method, you need to develop .NET 3.5 or higher. If you are using .NET 2.0 or 3.0, you can call the method as such

 arr = RemoveAt(arr, 1) 

Hope this is what you need.

Update

After running the tests based on the comment of ToolMakerSteve , the source code does not change the array you want to update, due to ByVal used in the function declaration. However, writing code like arr = arr.RemoveAt(1) or arr = RemoveAt(arr, 1) changes the array because it reassigns the changed array to the original.

Find below the updated method (subroutine) to remove an element from the array.

 <System.Runtime.CompilerServices.Extension()> _ Public Sub RemoveAt(Of T)(ByRef arr As T(), ByVal index As Integer) Dim uBound = arr.GetUpperBound(0) Dim lBound = arr.GetLowerBound(0) Dim arrLen = uBound - lBound If index < lBound OrElse index > uBound Then Throw New ArgumentOutOfRangeException( _ String.Format("Index must be from {0} to {1}.", lBound, uBound)) Else 'create an array 1 element less than the input array Dim outArr(arrLen - 1) As T 'copy the first part of the input array Array.Copy(arr, 0, outArr, 0, index) 'then copy the second part of the input array Array.Copy(arr, index + 1, outArr, index, uBound - index) arr = outArr End If End Sub 

Using the method is similar to the original, except this time there is no return value, so trying to assign an array from the return value will not work because nothing is returned.

 Dim arr = New String() {"abc", "mno", "xyz"} arr.RemoveAt(1) ' Output: {"abc", "mno"} (works on .NET 3.5 and higher) RemoveAt(arr, 1) ' Output: {"abc", "mno"} (works on all versions of .NET fx) arr = arr.RemoveAt(1) 'will not work; no return value arr = RemoveAt(arr, 1) 'will not work; no return value 

Note:

  • I use a temporary array for the process because it makes my intentions clear, and that is exactly what VB.NET does behind the scenes when you make Redim Preserve . If you want to change the array in place using Redim Preserve , see ToolmakerSteve's answer .
  • The RemoveAt methods described here are extension methods. For them to work, you need to insert them into the Module . Extension methods will not work in VB.NET if they are placed in Class .

  • Important If you are modifying an array with a lot of "deletes", it is strongly recommended that you use a different data structure, such as List(Of T) , as suggested by other respondents for this question.

+13
source

You can not. I would suggest that you put the elements of an array in a List , at least you can remove the elements. An array can be expanded, for example, using ReDim , but you cannot delete array elements after they are created. You will need to rebuild the array from scratch to do this.

If you can avoid this, do not use arrays here, use List .

+11
source

It depends on what you mean by deletion. The array has a fixed size, so deleting does not make sense.

If you want to delete element i , one option would be to move all elements j > i one position to the left ( a[j - 1] = a[j] for all j or using Array.Copy ), and then resize the array using ReDim Preserve .

So, if you are not forced to use an array by external constraint, consider using a data structure that is more suitable for adding and removing elements. List <T> , for example, also uses an array internally, but takes care of all the problems of resizing itself. To remove elements, it uses the algorithm mentioned above (without ReDim), so List<T>.RemoveAt is an O (n) operation .

In the System.Collections.Generic space, there are many different collection classes optimized for different use cases. If removal of items is often required, there are many better options than an array (or even List<T> ).

+4
source

Yes, you can remove an element from the array. Here is an extension method that moves elements as needed, and then resizes the array shorter:

 ' Remove element at index "index". Result is one element shorter. ' Similar to List.RemoveAt, but for arrays. <System.Runtime.CompilerServices.Extension()> _ Public Sub RemoveAt(Of T)(ByRef a() As T, ByVal index As Integer) ' Move elements after "index" down 1 position. Array.Copy(a, index + 1, a, index, UBound(a) - index) ' Shorten by 1 element. ReDim Preserve a(UBound(a) - 1) End Sub 

Usage examples (assuming the array starts at index 0):

 Dim a() As String = {"Albert", "Betty", "Carlos", "David"} a.RemoveAt(0) ' Remove first element => {"Betty", "Carlos", "David"} a.RemoveAt(1) ' Remove second element => {"Betty", "David"} a.RemoveAt(UBound(a)) ' Remove last element => {"Betty"} 

Removing the First or Last element is common, so convenient procedures are used for this (I like the code that more clearly reflects my intent):

 <System.Runtime.CompilerServices.Extension()> _ Public Sub DropFirstElement(Of T)(ByRef a() As T) a.RemoveAt(0) End Sub <System.Runtime.CompilerServices.Extension()> _ Public Sub DropLastElement(Of T)(ByRef a() As T) a.RemoveAt(UBound(a)) End Sub 

Using:

 a.DropFirstElement() a.DropLastElement() 

And as Heinzi said, if you do, use List (Of T) instead, if possible. The list already has a "RemoveAt" routine and other routines useful for inserting / removing items.

+4
source

One line using LINQ:

 Dim arr() As String = {"uno", "dos", "tres", "cuatro", "cinco"} Dim indx As Integer = 2 arr = arr.Where(Function(item, index) index <> indx).ToArray 'arr = {"uno", "dos", "cuatro", "cinco"} 

Delete first item:

 arr = arr.Skip(1).ToArray 

Delete last item:

 arr = arr.Take(arr.length - 1).ToArray 
+4
source

My favorite way:

 Imports System.Runtime.CompilerServices <Extension()> _ Public Sub RemoveAll(Of T)(ByRef arr As T(), matching As Predicate(Of T)) If Not IsNothing(arr) Then If arr.Count > 0 Then Dim ls As List(Of T) = arr.ToList ls.RemoveAll(matching) arr = ls.ToArray End If End If End Sub 

Then in the code, when I need to remove something from the array, I can do this using some property in some object in this array that has a specific value, for example:

 arr.RemoveAll(Function(c) c.MasterContactID.Equals(customer.MasterContactID)) 

Or, if I already know the exact object that I want to delete, I can simply do:

 arr.RemoveAll(function(c) c.equals(customer)) 
+3
source

The variable i represents the index of the element you want to remove:

 System.Array.Clear(ArrayName, i, 1) 
+2
source

It may be a lazy solution, but you canโ€™t just delete the contents of the index you want to delete by reassigning their values โ€‹โ€‹to 0 or "" and then ignore / skip these empty array elements instead of recreating and copying arrays on and off?

+1
source
 Public Sub ArrayDelAt(ByRef x As Array, ByVal stack As Integer) For i = 0 To x.Length - 2 If i >= stack Then x(i) = x(i + 1) x(x.Length-1) = Nothing End If Next End Sub 

try it

+1
source

It sounds like more complicated than ...

  Dim myArray As String() = TextBox1.Lines 'First we count how many null elements there are... Dim Counter As Integer = 0 For x = 0 To myArray.Count - 1 If Len(myArray(x)) < 1 Then Counter += 1 End If Next 'Then we dimension an array to be the size of the last array 'minus the amount of nulls found... Dim tempArr(myArray.Count - Counter) As String 'Indexing starts at zero, so let set the stage for that... Counter = -1 For x = 0 To myArray.Count - 1 'Set the conditions for the new array as in 'It .contains("word"), has no value, length is less than 1, ect. If Len(myArray(x)) > 1 Then Counter += 1 'So if a value is present, we move that value over to 'the new array. tempArr(Counter) = myArray(x) End If Next 

Now you can assign tempArr back to the original or what you need to do with it, as in ...

TextBox1.Lines = tempArr (now you have an empty field empty)

0
source

If the array is a string array, you can do the following:

 AlphaSplit = "a\b\c".Split("\") MaxIndex = AlphaSplit.GetUpperBound(0) AlphaSplit = AlphaSplit.Where(Function(item, index) index <> MaxIndex).ToArray AlphaJoin = String.Join("\", PublishRouteSplit) 
0
source

All Articles