Come eliminare un elemento da un array in C #


153

Diciamo che ho questo array,

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

Come posso eliminare un elemento con "nome"? , diciamo il numero 4?

Anche ArrayListnon ha aiutato a eliminare?

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);
}

Cosa succede se si hanno valori duplicati nell'elenco? Vuoi rimuovere solo la prima istanza o tutte le istanze?
BenAlabaster,

si, non ho valori duplicati, qualche idea?
Ahmed

ahmed Intendi dire, no, non sì o sì? (non insultare il tuo inglese, solo chiedere chiarimenti)
Malfist,

@Malfist - scusa :), intendevo dire che non mi importa dei valori duplicati perché sono sicuro che non ce ne sono nel mio caso, grazie ancora
ahmed

3
Non è possibile rimuovere elementi dagli array in C #, come si può vedere da questo programma di esempio . Quello che puoi fare è creare un nuovo array, copiare solo alcuni degli elementi di quello originale e assegnarlo nuovamente alla variabile originale. Questo è ciò che viene fatto in tutte le risposte.
Nicola Musatti,

Risposte:


340

Se si desidera rimuovere tutte le istanze di 4 senza conoscere l'indice:

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();

Se vuoi rimuovere solo la prima istanza:

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();

Modifica: nel caso in cui non l'avessi già capito, come ha sottolineato Malfist, devi scegliere come target .NET Framework 3.5 affinché gli esempi di codice LINQ funzionino. Se scegli come target 2.0 devi fare riferimento agli esempi non LINQ.


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

21

È inoltre possibile convertire l'array in un elenco e chiamare rimuovi nell'elenco. È quindi possibile riconvertire nuovamente l'array.

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

11

Il codice scritto nella domanda contiene un bug

Il tuo arraylist contiene stringhe di "1" "3" "4" "9" e "2" (nota gli spazi)

Quindi IndexOf (4) non troverà nulla perché 4 è un int e anche "tostring" lo convertirà in "4" e non in "4", e nulla verrà rimosso.

Un arraylist è il modo corretto di fare ciò che vuoi.


Elenco <T> sarebbe meglio di ArrayList.
Mike Scott,

1
Questa risposta merita più voti. Sebbene io sia assolutamente d'accordo con @MikeScott sul fatto che List<T>sarebbe meglio di ArrayList, questa sembra essere l'unica risposta che identifica correttamente il problema che l'OP ha avuto quando ha cercato di usare ArrayList per risolvere il suo problema originale. L'OP ha capito che non è possibile ridimensionare le matrici, che nessun altro sembra aver notato, e ha provato a utilizzare un tipo ridimensionabile, che nessun altro sembra aver notato, e quindi è stato inciampato da un problema diverso, che nessun altro sembra aver notato.
phoog,

5

La risposta di Balabaster è corretta se si desidera rimuovere tutte le istanze dell'elemento. Se vuoi rimuovere solo il primo, dovresti fare qualcosa del genere:

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();
}

5

Ho pubblicato la mia soluzione qui .

Questo è un modo per eliminare un elemento dell'array senza copiarlo in un altro array - proprio nel frame della stessa istanza dell'array:

    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);
    }

4
Il ridimensionamento in realtà copia i dati in un nuovo array (a meno che la nuova dimensione passata non sia la lunghezza dell'array passato); non cambia la dimensione dell'istanza dell'array passata. Ecco perché è un parametro di riferimento. Vedere riferimentiource.microsoft.com/mscorlib/R/71074deaf111c4e3.html .
phoog,

5

La rimozione da un array stesso non è semplice, poiché è necessario occuparsi del ridimensionamento. Questo è uno dei grandi vantaggi dell'utilizzo di qualcosa come un List<int>invece. Fornisce Remove/ RemoveAtin 2.0 e molte estensioni LINQ per 3.0.

Se è possibile, refactoring per utilizzare un List<>o simile.


Penso che sia la soluzione migliore in questo caso.
Bogdan Doicin,

3

Come estensione generica, compatibile 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();
    }
}

Uso:

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

0

' Per rimuovere elementi dalla stringa in base ai valori chiave del dizionario. 'Codice 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()

0

Puoi fare in questo modo:

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();        
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.