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)

注意:

  1. 我使用临时数组进行处理,因为它使我的意图清晰,这正是VB.NET在幕后做的事情Redim Preserve.如果您想使用原位修改数组Redim Preserve,请参阅ToolmakerSteve的答案.
  2. RemoveAt这里编写的方法是扩展方法.为了让它们工作,你必须将它们粘贴在一个Module.如果将扩展方法放在一个中,扩展方法将无法在VB.NET中使用Class.

  3. 重要提示如果您将使用大量"删除"修改数组,强烈建议使用不同的数据结构,例如List(Of T)其他回答者对此问题的建议.


Jas*_*ans 11

你不能.我建议你把数组元素放到一个List,至少然后你可以删除项目.可以扩展数组,例如使用ReDim但是一旦创建了数组元素就无法删除它们.你必须从头开始重建数组才能做到这一点.

如果你可以避免它,不要在这里使用数组,使用a List.


Iva*_*lla 7

使用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)


Hei*_*nzi 5

这取决于您所说的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>)更好的选择。


Too*_*eve 5

是的,您可以从数组中删除一个元素。这是一种扩展方法,可以根据需要移动元素,然后将数组大小调整得更短:

' 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”子例程,以及其他可用于插入/删除元素的例程。