Comment puis-je supprimer un élément d'un tableau dans VB.NET ?
Comme Heinzi l'a dit, un tableau a une taille fixe. Afin de «supprimer un élément» ou de le «redimensionner», vous devez créer un nouveau tableau avec la taille souhaitée et copier les éléments dont vous avez besoin.
Voici le code pour supprimer un élément d'un tableau:
<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
Vous pouvez l'utiliser comme tel:
Module Module1
Sub Main()
Dim arr = New String() {"abc", "mno", "xyz"}
arr.RemoveAt(1)
End Sub
End Module
Le code ci-dessus supprime le deuxième élément ("mno"
) [qui a un index de 1] du tableau.
Vous devez développer sous .NET 3.5 ou supérieur pour pouvoir utiliser la méthode d'extension . Si vous utilisez .NET 2.0 ou 3.0, vous pouvez appeler la méthode en tant que telle.
arr = RemoveAt(arr, 1)
J'espère que c'est ce dont vous avez besoin.
Après l'exécution de tests basés sur Commentaire de ToolMakerSteve , il semble que le code initial ne modifie pas le tableau que vous souhaitez mettre à jour en raison de la variable ByVal
utilisée dans la déclaration de la fonction. Cependant, écrire un code tel que arr = arr.RemoveAt(1)
ou arr = RemoveAt(arr, 1)
modifie le tableau car il réaffecte le tableau modifié à l'original.
Trouvez ci-dessous la méthode mise à jour (sous-routine) pour supprimer un élément d'un tableau.
<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
L'utilisation de la méthode est similaire à la méthode d'origine, à l'exception du fait qu'il n'y a pas de valeur de retour cette fois-ci. Par conséquent, essayer d'affecter un tableau à partir de la valeur de retour ne fonctionnera pas car rien n'est renvoyé.
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
Remarque:
Redim Preserve
. Si vous souhaitez modifier le tableau sur place à l'aide de Redim Preserve
, voir Réponse de ToolmakerSteve .Les méthodes RemoveAt
écrites ici sont des méthodes d'extension. Pour qu’ils fonctionnent, vous devrez les coller dans un Module
. Les méthodes d'extension ne fonctionneront pas dans VB.NET si elles sont placées dans une Class
.
Important Si vous souhaitez modifier votre tableau avec beaucoup de 'supprime', il est vivement recommandé d'utiliser une structure de données différente telle que List(Of T)
, comme suggéré par les autres répondants à cette question.
Tu ne peux pas. Je suggérerais que vous mettiez les éléments de tableau dans un List
, au moins, vous pourrez supprimer des éléments. Un tableau peut être étendu, par exemple en utilisant ReDim
mais vous ne pouvez pas supprimer les éléments du tableau une fois qu'ils ont été créés. Pour ce faire, vous devrez reconstruire le tableau à partir de zéro.
Si vous pouvez l'éviter, n'utilisez pas de tableaux ici, utilisez un List
.
Cela dépend de ce que vous entendez par delete. Un tableau a une taille fixe, la suppression n'a donc aucun sens.
Si vous souhaitez supprimer l'élément i
, une option serait de déplacer tous les éléments j > i
d'une position vers la gauche (a[j - 1] = a[j]
pour tous les j
ou d'utiliser Array.Copy
), puis de redimensionner le tableau à l'aide de ReDim Preserve .
Par conséquent, à moins que vous ne soyez obligé d'utiliser un tableau en raison de contraintes externes, envisagez d'utiliser une structure de données plus appropriée pour l'ajout et la suppression d'éléments. (Liste <T> }, par exemple, utilise également un tableau en interne mais s’occupe lui-même de tous les problèmes de redimensionnement: Pour supprimer des éléments, il utilise l’algorithme mentionné ci-dessus (sans le ReDim), raison pour laquelle List<T>.RemoveAt
est une opération O(n) }.
Il y a beaucoup de classes de collection différentes dans l'espace de noms System.Collections.Generic , optimisées pour différents cas d'utilisation. Si la suppression d'éléments est souvent une exigence, il existe de nombreuses meilleures options qu'un tableau (ou même List<T>
).
Oui, vous pouvez supprimer un élément d'un tableau. Voici une méthode d'extension qui déplace les éléments selon les besoins, puis redimensionne le tableau plus rapidement:
' 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
Exemples d’utilisation (en supposant que le tableau commence par l’indice 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"}
La suppression du premier ou du dernier élément est courante. Il existe donc des routines de commodité pratiques (j'aime le code qui exprime mon intention de manière plus lisible):
<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()
Et comme Heinzi l'a dit, si vous vous trouvez dans cette situation, utilisez plutôt List (Of T), si possible. La liste a déjà un sous-programme "RemoveAt" et d'autres routines utiles pour l'insertion/suppression d'éléments.
Une ligne utilisant 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"}
Supprimer le premier élément:
arr = arr.Skip(1).ToArray
Supprimer le dernier élément:
arr = arr.Take(arr.length - 1).ToArray
Ma manière préférée:
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
Ensuite, dans le code, chaque fois que je dois supprimer quelque chose d'un tableau, je peux le faire en utilisant une propriété dans un objet de ce tableau ayant une certaine valeur, comme:
arr.RemoveAll(Function(c) c.MasterContactID.Equals(customer.MasterContactID))
Ou si je connais déjà l'objet exact que je veux supprimer, je peux simplement faire:
arr.RemoveAll(function(c) c.equals(customer))
La variable i
représente l'index de l'élément que vous souhaitez supprimer:
System.Array.Clear(ArrayName, i, 1)
Cela peut être une solution de type paresseux, mais vous ne pouvez pas simplement supprimer le contenu de l'index que vous souhaitez supprimer en réaffectant leurs valeurs à 0 ou "" puis en ignorant/ignorant ces éléments de tableau vides au lieu de recréer et de copier des tableaux ?
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
essaye ça
On dirait que ça a l'air plus compliqué que ça ...
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
Vous pouvez maintenant attribuer à tempArr l'original ou tout ce dont vous avez besoin, comme dans ...
TextBox1.Lines = tempArr (vous avez maintenant une zone de texte vide de lignes vides)
Si le tableau est un tableau de chaînes, vous pouvez alors procéder comme suit:
AlphaSplit = "a\b\c".Split("\")
MaxIndex = AlphaSplit.GetUpperBound(0)
AlphaSplit = AlphaSplit.Where(Function(item, index) index <> MaxIndex).ToArray
AlphaJoin = String.Join("\", PublishRouteSplit)