web-dev-qa-db-fra.com

Comment puis-je supprimer un élément d'un tableau dans VB.NET?

Comment puis-je supprimer un élément d'un tableau dans VB.NET ?

26
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.

Mettre à jour

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: 

  1. J'utilise un tableau temporaire pour le processus car cela clarifie mes intentions et c'est exactement ce que VB.NET fait en coulisse lorsque vous faites Redim Preserve. Si vous souhaitez modifier le tableau sur place à l'aide de Redim Preserve, voir Réponse de ToolmakerSteve .
  2. 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

  3. 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.

13
Alex Essilfie

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.

11
Jason Evans

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>).

4
Heinzi

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.

4
ToolmakerSteve

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
4
Ivan Ferrer Villa

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))
3
Derek Ziemba

La variable i représente l'index de l'élément que vous souhaitez supprimer:

System.Array.Clear(ArrayName, i, 1)
2
Vinayak D.Gaikwad

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 ?

1
Derphausen
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

1
Lulu Lovely

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)

0
Thurman Jenner

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)
0
Herschel