Comment supprimer un élément d'un tableau en C #

153

Disons que j'ai ce tableau,

int[] numbers = {1, 3, 4, 9, 2};

Comment puis-je supprimer un élément par "nom"? , disons le numéro 4?

Même ArrayListpas aidé à supprimer?

string strNumbers = " 1, 3, 4, 9, 2";
ArrayList numbers = new ArrayList(strNumbers.Split(new char[] { ',' }));
numbers.RemoveAt(numbers.IndexOf(4));
foreach (var n in numbers)
{
    Response.Write(n);
}
ahmed
la source
Que faire si vous avez des valeurs en double dans votre liste? Voulez-vous simplement supprimer la première instance ou toutes les instances?
BenAlabaster
oui, je n'ai pas de valeurs en double, aucune idée?
ahmed
ahmed Voulez-vous dire, non, vous ne le faites pas, ou oui vous le faites? (ne pas insulter votre anglais, juste demander des éclaircissements)
Malfist
@Malfist - désolé :), je voulais dire que je ne me soucie pas des valeurs en double parce que je suis sûr qu'il n'y en a pas dans mon cas, merci encore
ahmed
3
Vous ne pouvez pas supprimer des éléments des tableaux en C #, comme vous pouvez le voir dans cet exemple de programme . Ce que vous pouvez faire est de créer un nouveau tableau, de copier uniquement certains des éléments de l'original et de le réattribuer à la variable d'origine. C'est ce qui est fait dans toutes les réponses.
Nicola Musatti

Réponses:

340

Si vous souhaitez supprimer toutes les instances de 4 sans avoir besoin de connaître l'index:

LINQ: (.NET Framework 3.5)

int[] numbers = { 1, 3, 4, 9, 2 };
int numToRemove = 4;
numbers = numbers.Where(val => val != numToRemove).ToArray();

Non-LINQ: (.NET Framework 2.0)

static bool isNotFour(int n)
{
    return n != 4;
}

int[] numbers = { 1, 3, 4, 9, 2 };
numbers = Array.FindAll(numbers, isNotFour).ToArray();

Si vous souhaitez supprimer uniquement la première instance:

LINQ: (.NET Framework 3.5)

int[] numbers = { 1, 3, 4, 9, 2, 4 };
int numToRemove = 4;
int numIndex = Array.IndexOf(numbers, numToRemove);
numbers = numbers.Where((val, idx) => idx != numIndex).ToArray();

Non-LINQ: (.NET Framework 2.0)

int[] numbers = { 1, 3, 4, 9, 2, 4 };
int numToRemove = 4;
int numIdx = Array.IndexOf(numbers, numToRemove);
List<int> tmp = new List<int>(numbers);
tmp.RemoveAt(numIdx);
numbers = tmp.ToArray();

Edit: Juste au cas où vous ne l'auriez pas déjà compris, comme l'a souligné Malfist, vous devez cibler le .NET Framework 3.5 pour que les exemples de code LINQ fonctionnent. Si vous ciblez 2.0, vous devez référencer les exemples non-LINQ.

BenAlabaster
la source
32
int[] numbers = { 1, 3, 4, 9, 2 };
numbers = numbers.Except(new int[]{4}).ToArray();
Meetjaydeep
la source
21

Vous pouvez également convertir votre tableau en liste et appeler remove sur la liste. Vous pouvez ensuite reconvertir dans votre tableau.

int[] numbers = {1, 3, 4, 9, 2};
var numbersList = numbers.ToList();
numbersList.Remove(4);
Dave DP
la source
11

Le code qui est écrit dans la question contient un bogue

Votre arraylist contient des chaînes de "1" "3" "4" "9" et "2" (notez les espaces)

Donc IndexOf (4) ne trouvera rien parce que 4 est un int, et même "tostring" le convertirait en "4" et non en "4", et rien ne sera supprimé.

Un arraylist est la bonne façon de faire ce que vous voulez.

DevinB
la source
List <T> serait mieux que ArrayList.
Mike Scott
1
Cette réponse mérite plus de votes positifs. Bien que je sois tout à fait d'accord avec @MikeScott que ce List<T>serait mieux que ArrayList, cela semble être la seule réponse qui identifie correctement le problème rencontré par l'OP lorsqu'il a essayé d'utiliser ArrayList pour résoudre son problème d'origine. L'OP a compris que vous ne pouvez pas redimensionner les tableaux, ce que personne d'autre ne semble avoir remarqué, et a essayé d'utiliser un type redimensionnable à la place, que personne d'autre ne semble avoir remarqué, puis a été déclenché par un problème différent, ce que personne d'autre ne semble avoir remarqué.
phoog le
5

La réponse de Balabaster est correcte si vous souhaitez supprimer toutes les instances de l'élément. Si vous souhaitez supprimer uniquement le premier, vous feriez quelque chose comme ceci:

int[] numbers = { 1, 3, 4, 9, 2, 4 };
int numToRemove = 4;
int firstFoundIndex = Array.IndexOf(numbers, numToRemove);
if (numbers >= 0)
{
    numbers = numbers.Take(firstFoundIndex).Concat(numbers.Skip(firstFoundIndex + 1)).ToArray();
}
Vojislav Stojkovic
la source
5

J'ai posté ma solution ici .

C'est un moyen de supprimer un élément de tableau sans copier dans un autre tableau - juste dans le cadre de la même instance de tableau:

    public static void RemoveAt<T>(ref T[] arr, int index)
    {
        for (int a = index; a < arr.Length - 1; a++)
        {
            // moving elements downwards, to fill the gap at [index]
            arr[a] = arr[a + 1];
        }
        // finally, let's decrement Array's size by one
        Array.Resize(ref arr, arr.Length - 1);
    }
infografnet
la source
4
Resize copie en fait les données dans un nouveau tableau (à moins que la nouvelle taille transmise soit la longueur du tableau passé); cela ne change pas la taille de l'instance de tableau transmise. C'est pourquoi c'est un paramètre de référence. Voir referencesource.microsoft.com/mscorlib/R/71074deaf111c4e3.html .
phoog
5

La suppression d'un tableau lui-même n'est pas simple, car vous devez alors faire face au redimensionnement. C'est l'un des grands avantages d'utiliser quelque chose comme un à la List<int>place. Il fournit Remove/ RemoveAtin 2.0 et de nombreuses extensions LINQ pour 3.0.

Si vous le pouvez, refactorisez pour utiliser un List<>fichier.

ctacke
la source
Je pense que c'est la meilleure solution dans ce cas.
Bogdan Doicin
3

En tant qu'extension générique, compatible 2.0:

using System.Collections.Generic;
public static class Extensions {
    //=========================================================================
    // Removes all instances of [itemToRemove] from array [original]
    // Returns the new array, without modifying [original] directly
    // .Net2.0-compatible
    public static T[] RemoveFromArray<T> (this T[] original, T itemToRemove) {  
        int numIdx = System.Array.IndexOf(original, itemToRemove);
        if (numIdx == -1) return original;
        List<T> tmp = new List<T>(original);
        tmp.RemoveAt(numIdx);
        return tmp.ToArray();
    }
}

Usage:

int[] numbers = {1, 3, 4, 9, 2};
numbers = numbers.RemoveFromArray(4);
Petrucio
la source
0

' Pour supprimer des éléments de la chaîne en fonction des valeurs de clé du dictionnaire. 'Code VB.net

 Dim stringArr As String() = "file1,file2,file3,file4,file5,file6".Split(","c)
 Dim test As Dictionary(Of String, String) = New Dictionary(Of String, String)
 test.Add("file3", "description")
 test.Add("file5", "description")
 stringArr = stringArr.Except(test.Keys).ToArray()
SP007
la source
0

Vous pouvez faire de cette manière:

int[] numbers= {1,3,4,9,2};     
List<int> lst_numbers = new List<int>(numbers);
int required_number = 4;
int i = 0;
foreach (int number in lst_numbers)
{              
    if(number == required_number)
    {
        break;
    }
    i++;
}
lst_numbers.RemoveAt(i);
numbers = lst_numbers.ToArray();        

la source