如何从一个VB.NET数组中删除一个元素?
正如Heinzi所说,数组具有固定的大小。为了“删除一个项”或“调整大小”,您需要创建一个具有所需大小的新数组,并适当地复制所需的项。
以下是从数组中删除一项的代码:
<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
Module Module1
Sub Main()
Dim arr = New String() {"abc", "mno", "xyz"}
arr.RemoveAt(1)
End Sub
End Module
上面的代码从数组中删除了第二个元素(索引为1的"mno"
)。
您需要在 .NET 3.5 或更高版本中开发才能使用该扩展方法。 如果您正在使用 .NET 2.0 或 3.0,则可以按如下方式调用该方法
arr = RemoveAt(arr, 1)
我希望这是你需要的。
在根据ToolMakerSteve的评论运行测试后,发现最初的代码由于函数声明中使用了ByVal
,无法修改要更新的数组。然而,写类似于arr = arr.RemoveAt(1)
或arr = RemoveAt(arr, 1)
的代码可以修改数组,因为它将修改后的数组重新赋值给原始数组。
下面是更新后从数组中删除元素的方法(子程序)。
<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
这种方法的使用方式与原始方法类似,但这次没有返回值,因此尝试从返回值中分配数组将不起作用,因为没有返回任何内容。
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
注意:
我在这个过程中使用了一个临时数组,因为这使我的意图清晰明确,而这正是VB.NET在幕后执行的操作,当你使用Redim Preserve
时。如果您想使用Redim Preserve
原地修改数组,请参见ToolmakerSteve的答案。
这里编写的RemoveAt
方法是扩展方法。为了使它们起作用,您必须将它们粘贴到一个Module
中。如果将扩展方法放置在Class
中,则无法在VB.NET中使用。
重要提示: 如果您将使用大量“删除”来修改数组,则强烈建议使用其他数据结构,例如此问题的其他回答者建议的List(Of T)
。
无法删除数组元素,建议将数组元素放入List
中,至少你可以删除其中的项。可以使用ReDim
扩展数组,但是一旦创建了数组元素就无法删除,必须从头开始重建数组。
如果可能的话,不要在此处使用数组,而要使用List
。
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"}
删除第一个元素:
arr = arr.Skip(1).ToArray
删除最后一个元素:
arr = arr.Take(arr.length - 1).ToArray
j> i
向左移动一个位置(对于所有 j
, a [j-1] = a [j]
或使用 Array.Copy
),然后使用 ReDim Preserve 调整数组大小。List<T>.RemoveAt
是O(n)操作的原因。 List<T>
)更好的选择。是的,你可以从一个数组中删除一个元素。以下是一个扩展方法,它根据需要移动元素,然后将数组大小调整为较短:
' 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
使用示例(假设数组从索引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"}
删除第一个或最后一个元素很常见,因此这里提供了方便的例程来实现(我喜欢代码更加易读地表达我的意图):
<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
使用方法:
a.DropFirstElement()
a.DropLastElement()
正如Heinzi所说,如果你发现自己在这样做,请尽可能使用List(Of T)。 List已经有“RemoveAt”子程序,以及其他有用于插入/删除元素的例程。
我最喜欢的方式是:
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
在代码中,每当我需要从数组中删除某些内容时,可以通过该数组中某个对象的某个属性具有特定值来实现,例如:
arr.RemoveAll(Function(c) c.MasterContactID.Equals(customer.MasterContactID))
或者,如果我已经知道要删除的确切对象,可以直接执行以下操作:
arr.RemoveAll(function(c) c.equals(customer))
System.Array.Clear(ArrayName, i, 1)
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
AlphaSplit = "a\b\c".Split("\")
MaxIndex = AlphaSplit.GetUpperBound(0)
AlphaSplit = AlphaSplit.Where(Function(item, index) index <> MaxIndex).ToArray
AlphaJoin = String.Join("\", PublishRouteSplit)