Cómo eliminar un elemento de una matriz en C #


153

Digamos que tengo esta matriz,

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

¿Cómo puedo eliminar un elemento por "nombre"? , digamos el número 4?

Incluso ArrayListno ayudó a eliminar?

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

¿Qué pasa si tiene valores duplicados en su lista? ¿Desea simplemente eliminar la primera instancia o todas las instancias?
BenAlabaster

sí, no tengo valores duplicados, ¿alguna idea?
ahmed

ahmed ¿Quieres decir, no, no lo haces, o sí lo haces? (no insulta tu inglés, solo pide una aclaración)
Malfist

@Malfist - lo siento :), quise decir que no me importan los valores duplicados porque estoy seguro de que no hay ninguno de ellos en mi caso, gracias de nuevo
ahmed

3
No puede eliminar elementos de las matrices en C #, como puede ver en este programa de ejemplo . Lo que puede hacer es crear una nueva matriz, copiar solo algunos de los elementos de la original y asignarla nuevamente a la variable original. Esto es lo que se hace en todas las respuestas.
Nicola Musatti

Respuestas:


340

Si desea eliminar todas las instancias de 4 sin necesidad de conocer el índice:

LINQ: (.NET Framework 3.5)

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

No 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 desea eliminar solo la primera instancia:

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

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

Editar: en caso de que aún no lo haya descubierto, como señaló Malfist, debe apuntar a .NET Framework 3.5 para que los ejemplos de código LINQ funcionen. Si está apuntando a 2.0, debe hacer referencia a los ejemplos que no son de LINQ.


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

21

También puede convertir su matriz en una lista y llamar a eliminar en la lista. Luego puede volver a convertir a su matriz.

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

11

El código que está escrito en la pregunta tiene un error

Su lista de arrays contiene cadenas de "1" "3" "4" "9" y "2" (observe los espacios)

Por lo tanto, IndexOf (4) no encontrará nada porque 4 es un int, e incluso "tostring" lo convertiría a "4" y no a "4", y no se eliminará nada.

Una lista de arrays es la forma correcta de hacer lo que quiere.


List <T> sería mejor que ArrayList.
Mike Scott

1
Esta respuesta merece más votos a favor. Si bien estoy absolutamente de acuerdo con @MikeScott que List<T>sería mejor que ArrayList, esta parece ser la única respuesta que identifica correctamente el problema que tuvo el OP cuando intentó usar ArrayList para resolver su problema original. El OP entendió que no puede cambiar el tamaño de las matrices, que nadie más parece haber notado, e intentó usar un tipo redimensionable en su lugar, que nadie más parece haber notado, y luego se tropezó con un problema diferente, que nadie más parece Haber notado.
phoog

5

La respuesta de Balabaster es correcta si desea eliminar todas las instancias del elemento. Si desea eliminar solo el primero, haría algo como esto:

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

Publiqué mi solución aquí .

Esta es una forma de eliminar un elemento de matriz sin copiar a otra matriz, solo en el marco de la misma instancia de matriz:

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

44
Cambiar el tamaño realmente copia los datos a una nueva matriz (a menos que el nuevo tamaño aprobado sea la longitud de la matriz aprobada); no cambia el tamaño de la instancia de matriz pasada. Por eso es un parámetro de referencia. Consulte referencesource.microsoft.com/mscorlib/R/71074deaf111c4e3.html .
phoog

5

Eliminar de una matriz en sí no es simple, ya que luego tiene que lidiar con el cambio de tamaño. Esta es una de las grandes ventajas de usar algo como un List<int>en su lugar. Proporciona Remove/ RemoveAten 2.0 y muchas extensiones de LINQ para 3.0.

Si puede, refactorice para usar ao List<>similar.


Creo que es la mejor solución en este caso.
Bogdan Doicin

3

Como una extensión genérica, compatible con 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

' Para eliminar elementos de la cadena en función de los valores clave del diccionario. 'Código 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

Puedes hacer de esta manera:

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();        
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.