Ale*_*fie 13
正如海因兹所说,阵列具有固定的大小.为了"删除项目"或"调整大小",您必须创建一个具有所需大小的新数组,并根据需要复制所需的项目.
这是从数组中删除项目的代码:
<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
Run Code Online (Sandbox Code Playgroud)
您可以这样使用它:
Module Module1
Sub Main()
Dim arr = New String() {"abc", "mno", "xyz"}
arr.RemoveAt(1)
End Sub
End Module
Run Code Online (Sandbox Code Playgroud)
上面的代码"mno"从数组中删除第二个元素()[索引为1].
您需要在.NET 3.5或更高版本中进行开发才能使用扩展方法.如果您使用的是.NET 2.0或3.0,则可以这样调用该方法
arr = RemoveAt(arr, 1)
Run Code Online (Sandbox Code Playgroud)
我希望这就是你所需要的.
在基于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
Run Code Online (Sandbox Code Playgroud)
该方法的用法类似于原始方法,但这次没有返回值,因此尝试从返回值分配数组将不起作用,因为没有返回任何内容.
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
Run Code Online (Sandbox Code Playgroud)
注意:
Redim Preserve.如果您想使用原位修改数组Redim Preserve,请参阅ToolmakerSteve的答案.RemoveAt这里编写的方法是扩展方法.为了让它们工作,你必须将它们粘贴在一个Module.如果将扩展方法放在一个中,扩展方法将无法在VB.NET中使用Class.
重要提示如果您将使用大量"删除"修改数组,强烈建议使用不同的数据结构,例如List(Of T)其他回答者对此问题的建议.
使用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"}
Run Code Online (Sandbox Code Playgroud)
删除第一个元素:
arr = arr.Skip(1).ToArray
Run Code Online (Sandbox Code Playgroud)
删除最后一个元素:
arr = arr.Take(arr.length - 1).ToArray
Run Code Online (Sandbox Code Playgroud)
这取决于您所说的delete是什么意思。数组具有固定大小,因此删除实际上没有意义。
如果要删除元素i,一种选择是将所有元素j > i向左移动一个位置(a[j - 1] = a[j]对于所有元素j或使用Array.Copy),然后使用ReDim Preserve调整数组大小。
因此,除非您因某些外部约束而被迫使用数组,否则请考虑使用更适合添加和删除项目的数据结构。例如,List<T>也在内部使用一个数组,但它自己处理所有调整大小的问题:对于删除项目,它使用上面提到的算法(没有 ReDim),这就是List<T>.RemoveAtO(n) 操作的原因。
System.Collections.Generic命名空间中有很多不同的集合类,针对不同的用例进行了优化。如果需要经常删除项目,那么有很多比数组(甚至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
Run Code Online (Sandbox Code Playgroud)
用法示例(假设数组从索引 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"}
Run Code Online (Sandbox Code Playgroud)
删除第一个或最后一个元素很常见,因此以下是执行此操作的便捷例程(我喜欢更易读地表达我的意图的代码):
<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
Run Code Online (Sandbox Code Playgroud)
用法:
a.DropFirstElement()
a.DropLastElement()
Run Code Online (Sandbox Code Playgroud)
正如 Heinzi 所说,如果您发现自己这样做,请尽可能使用 List(Of T)。List 已经有“RemoveAt”子例程,以及其他可用于插入/删除元素的例程。