如何从 VB.NET 中的数组中删除项目?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3448103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I delete an item from an array in VB.NET?
回答by Alex Essilfie
As Heinzi said, an array has a fixed size. In order to 'remove an item' or 'resize' it, you'll have to create a new array with the desired size and copy the items you need as appropriate.
正如 Heinzi 所说,数组的大小是固定的。为了“删除项目”或“调整大小”,您必须创建一个具有所需大小的新数组,并根据需要复制您需要的项目。
Here's code to remove an item from an 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
The code above removes the second element ("mno"
) [which has an index of 1] from the array.
上面的代码"mno"
从数组中删除了第二个元素 ( ) [其索引为 1]。
You need to be developing in .NET 3.5 or higher in order to use the extension method. If you're using .NET 2.0 or 3.0, you can call the method as such
您需要在 .NET 3.5 或更高版本中进行开发才能使用扩展方法。如果您使用的是 .NET 2.0 或 3.0,则可以这样调用该方法
arr = RemoveAt(arr, 1)
I hope this is what you need.
我希望这是你所需要的。
Update
更新
After running tests based on ToolMakerSteve's commentit appears the initial code does not modify the array you want to update because of the ByVal
used in the function's declaration. However, writing code like arr = arr.RemoveAt(1)
or arr = RemoveAt(arr, 1)
does modify the array because it reassigns the modified array to the original.
根据ToolMakerSteve 的评论运行测试后,初始代码似乎没有修改您要更新的数组,因为ByVal
在函数声明中使用了 。但是,编写代码类似于arr = arr.RemoveAt(1)
或arr = RemoveAt(arr, 1)
确实会修改数组,因为它将修改后的数组重新分配给原始数组。
Find below the updated method (subroutine) for removing an element from an 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
Usage of the method is similar to the original, except there is no return value this time 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 do
Redim Preserve
. If you would like to modify the array in-place usingRedim Preserve
, see ToolmakerSteve's answer. The
RemoveAt
methods written here are extension methods. In order for them to work, you will have to paste them in aModule
. Extension methods will not work in VB.NET if they are placed in aClass
.ImportantIf you will be modifying your array with lots of 'removes', it is highly recommended to use a different data structure such as
List(Of T)
as suggested by other answerers to this question.
- 我在该过程中使用了一个临时数组,因为它使我的意图更加明确,而这正是 VB.NET 在您这样做时在幕后所做的
Redim Preserve
。如果您想使用 就地修改数组Redim Preserve
,请参阅ToolmakerSteve 的回答。 RemoveAt
这里写的方法是扩展方法。为了让它们工作,您必须将它们粘贴到Module
. 扩展方法如果放在Class
.重要如果您要修改您的数组并进行大量“删除”,强烈建议使用不同的数据结构,例如
List(Of T)
其他回答者对该问题的建议。
回答by Jason Evans
You can't. I would suggest that you put the array elements into a List
, at least then you can remove items. An array can be extended, for example using ReDim
but you cannot remove array elements once they have been created. You would have to rebuild the array from scratch to do that.
你不能。我建议您将数组元素放入 a List
,至少您可以删除项目。可以扩展数组,例如使用,ReDim
但一旦创建数组元素就不能删除它们。您必须从头开始重建阵列才能做到这一点。
If you can avoid it, don't use arrays here, use a List
.
如果可以避免,请不要在此处使用数组,而应使用List
.
回答by Ivan Ferrer Villa
One line using LINQ:
一行使用 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"}
Remove first element:
删除第一个元素:
arr = arr.Skip(1).ToArray
Remove last element:
删除最后一个元素:
arr = arr.Take(arr.length - 1).ToArray
回答by Heinzi
That depends on what you mean by delete. An array has a fixed size, so deleting doesn't really make sense.
这取决于您所说的delete是什么意思。数组具有固定大小,因此删除实际上没有意义。
If you want to remove 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.
如果要删除元素i
,一种选择是将所有元素j > i
向左移动一个位置(a[j - 1] = a[j]
对于所有元素j
,或使用Array.Copy
),然后使用ReDim Preserve调整数组大小。
So, unless you are forced to use an array by some external constraint, consider using a data structure more suitable for adding and removing items. List<T>, for example, also uses an array internally but takes care of all the resizing issues itself: For removing items, it uses the algorithm mentioned above (without the ReDim), which is why List<T>.RemoveAt
is an O(n) operation.
因此,除非您因某些外部约束而被迫使用数组,否则请考虑使用更适合添加和删除项目的数据结构。例如,List<T>也在内部使用了一个数组,但它自己会处理所有调整大小的问题:对于删除项目,它使用上面提到的算法(没有 ReDim),这就是List<T>.RemoveAt
O(n) 操作的原因。
There's a whole lot of different collection classes in the System.Collections.Genericnamespace, optimized for different use cases. If removing items frequently is a requirement, there are lots of better options than an array (or even List<T>
).
System.Collections.Generic命名空间中有很多不同的集合类,针对不同的用例进行了优化。如果需要经常删除项目,那么有很多比数组(甚至List<T>
)更好的选择。
回答by ToolmakerSteve
Yes, you can delete an element from an array. Here is an extension method that moves the elements as needed, then resizes the array one 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 array starting with index 0):
用法示例(假设数组以索引 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 First or Last element is common, so here are convenience routines for doing so (I like code that expresses my intent more readably):
删除第一个或最后一个元素很常见,所以这里有一些方便的例程来这样做(我喜欢更易读地表达我的意图的代码):
<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
Usage:
用法:
a.DropFirstElement()
a.DropLastElement()
And as Heinzi said, if you find yourself doing this, instead use List(Of T), if possible. List already has "RemoveAt" subroutine, and other routines useful for inserting/deleting elements.
正如 Heinzi 所说,如果您发现自己这样做,请尽可能使用 List(Of T)。List 已经有“RemoveAt”子例程,以及其他用于插入/删除元素的例程。
回答by Derek Ziemba
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, whenever I need to remove something from an array I can do it by some property in some object in that array having a certain value, like:
然后在代码中,每当我需要从数组中删除某些内容时,我都可以通过该数组中某个对象中具有特定值的某些属性来完成,例如:
arr.RemoveAll(Function(c) c.MasterContactID.Equals(customer.MasterContactID))
Or if I already know the exact object I want to remove, I can just do:
或者,如果我已经知道要删除的确切对象,我可以这样做:
arr.RemoveAll(function(c) c.equals(customer))
回答by Vinayak D.Gaikwad
The variable i
represents the index of the element you want to delete:
该变量i
表示要删除的元素的索引:
System.Array.Clear(ArrayName, i, 1)
回答by Derphausen
This may be a lazy man's solution, but can't you just delete the contents of the index you want removed by reassigning their values to 0 or "" and then ignore/skip these empty array elements instead of recreating and copying arrays on and off?
这可能是一个懒人的解决方案,但是您不能通过将它们的值重新分配为 0 或 "" 来删除要删除的索引的内容,然后忽略/跳过这些空数组元素而不是重新创建和复制数组?
回答by Lulu Lovely
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 this
尝试这个
回答by Thurman Jenner
Seems like this sounds more complicated than it is...
似乎这听起来比它更复杂......
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's 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 ever you need done with it as in...
现在,您可以将 tempArr 分配回原始文件或您需要对其进行的任何操作,例如...
TextBox1.Lines = tempArr (You now have a textbox void of blank lines)
TextBox1.Lines = tempArr(您现在有一个没有空行的文本框)