sistemas resueltos recorrer matriz matrices llenar lineales inversa imprimir ejercicios ecuaciones dinamica consola c# .net arrays

c# - resueltos - Eliminar elemento de una matriz regular



matriz inversa (13)

Tengo una matriz de objetos Foo. ¿Cómo elimino el segundo elemento de la matriz?

Necesito algo similar a RemoveAt() pero para una matriz regular.


Aquí hay una pequeña colección de métodos de ayuda que produje en función de algunas de las respuestas existentes. Utiliza tanto extensiones como métodos estáticos con parámetros de referencia para una idealidad máxima:

public static class Arr { public static int IndexOf<TElement>(this TElement[] Source, TElement Element) { for (var i = 0; i < Source.Length; i++) { if (Source[i].Equals(Element)) return i; } return -1; } public static TElement[] Add<TElement>(ref TElement[] Source, params TElement[] Elements) { var OldLength = Source.Length; Array.Resize(ref Source, OldLength + Elements.Length); for (int j = 0, Count = Elements.Length; j < Count; j++) Source[OldLength + j] = Elements[j]; return Source; } public static TElement[] New<TElement>(params TElement[] Elements) { return Elements ?? new TElement[0]; } public static void Remove<TElement>(ref TElement[] Source, params TElement[] Elements) { foreach (var i in Elements) RemoveAt(ref Source, Source.IndexOf(i)); } public static void RemoveAt<TElement>(ref TElement[] Source, int Index) { var Result = new TElement[Source.Length - 1]; if (Index > 0) Array.Copy(Source, 0, Result, 0, Index); if (Index < Source.Length - 1) Array.Copy(Source, Index + 1, Result, Index, Source.Length - Index - 1); Source = Result; } }

En cuanto a rendimiento, es decente, pero probablemente podría mejorarse. Remove basa en IndexOf y se crea una nueva matriz para cada elemento que desea eliminar llamando a RemoveAt .

IndexOf es el único método de extensión, ya que no necesita devolver la matriz original. New acepta múltiples elementos de algún tipo para producir una nueva matriz de dicho tipo. Todos los demás métodos deben aceptar el conjunto original como referencia, de modo que no sea necesario asignar el resultado después, como ocurre internamente.

Hubiera definido un método Merge para fusionar dos matrices; sin embargo, eso ya se puede lograr con el método Add al pasar una matriz real frente a múltiples elementos individuales. Por lo tanto, Add se puede usar de las dos formas siguientes para unir dos conjuntos de elementos:

Arr.Add<string>(ref myArray, "A", "B", "C");

O

Arr.Add<string>(ref myArray, anotherArray);


Aquí hay una versión anterior que tengo que funciona en la versión 1.0 del framework .NET y no necesita tipos genéricos.

public static Array RemoveAt(Array source, int index) { if (source == null) throw new ArgumentNullException("source"); if (0 > index || index >= source.Length) throw new ArgumentOutOfRangeException("index", index, "index is outside the bounds of source array"); Array dest = Array.CreateInstance(source.GetType().GetElementType(), source.Length - 1); Array.Copy(source, 0, dest, 0, index); Array.Copy(source, index + 1, dest, index, source.Length - index - 1); return dest; }

Esto se usa así:

class Program { static void Main(string[] args) { string[] x = new string[20]; for (int i = 0; i < x.Length; i++) x[i] = (i+1).ToString(); string[] y = (string[])MyArrayFunctions.RemoveAt(x, 3); for (int i = 0; i < y.Length; i++) Console.WriteLine(y[i]); } }


Así es como lo hice ...

public static ElementDefinitionImpl[] RemoveElementDefAt( ElementDefinition[] oldList, int removeIndex ) { ElementDefinitionImpl[] newElementDefList = new ElementDefinitionImpl[ oldList.Length - 1 ]; int offset = 0; for ( int index = 0; index < oldList.Length; index++ ) { ElementDefinitionImpl elementDef = oldList[ index ] as ElementDefinitionImpl; if ( index == removeIndex ) { // This is the one we want to remove, so we won''t copy it. But // every subsequent elementDef will by shifted down by one. offset = -1; } else { newElementDefList[ index + offset ] = elementDef; } } return newElementDefList; }


Como de costumbre, llego tarde a la fiesta ...

Me gustaría agregar otra opción a la lista de soluciones bonitas ya presente. =)
Me gustaría ver esto como una buena oportunidad para Extensions.

Referencia: http://msdn.microsoft.com/en-us/library/bb311042.aspx

Entonces, definimos una clase estática y en ella, nuestro Método.
Después de eso, podemos utilizar nuestro método extendido de cualquier manera. =)

using System; namespace FunctionTesting { // The class doesn''t matter, as long as it''s static public static class SomeRandomClassWhoseNameDoesntMatter { // Here''s the actual method that extends arrays public static T[] RemoveAt<T>( this T[] oArray, int idx ) { T[] nArray = new T[oArray.Length - 1]; for( int i = 0; i < nArray.Length; ++i ) { nArray[i] = ( i < idx ) ? oArray[i] : oArray[i + 1]; } return nArray; } } // Sample usage... class Program { static void Main( string[] args ) { string[] myStrArray = { "Zero", "One", "Two", "Three" }; Console.WriteLine( String.Join( " ", myStrArray ) ); myStrArray = myStrArray.RemoveAt( 2 ); Console.WriteLine( String.Join( " ", myStrArray ) ); /* Output * "Zero One Two Three" * "Zero One Three" */ int[] myIntArray = { 0, 1, 2, 3 }; Console.WriteLine( String.Join( " ", myIntArray ) ); myIntArray = myIntArray.RemoveAt( 2 ); Console.WriteLine( String.Join( " ", myIntArray ) ); /* Output * "0 1 2 3" * "0 1 3" */ } } }


En una matriz normal, debe barajar todas las entradas de la matriz por encima de 2 y luego cambiar su tamaño usando el método de Redimensionar. Es mejor que uses una ArrayList.


Esta es una forma de eliminar un elemento de matriz, a partir de .Net 3.5, sin copiar a otra matriz, utilizando la misma instancia de matriz con Array.Resize<T> :

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


La naturaleza de las matrices es que su longitud es inmutable. No puede agregar ni eliminar ninguno de los elementos de la matriz.

Tendrá que crear una nueva matriz que sea un elemento más corto y copiar los elementos antiguos a la nueva matriz, excluyendo el elemento que desea eliminar.

Entonces, probablemente sea mejor usar una Lista en lugar de una matriz.


No es exactamente la forma de hacerlo, pero si la situación es trivial y usted valora su tiempo, puede probar esto para los tipos que aceptan nulos.

Foos[index] = null

y luego verifica si hay entradas nulas en tu lógica ...


Si no quieres usar List:

var foos = new List<Foo>(array); foos.RemoveAt(index); return foos.ToArray();

Podrías probar este método de extensión que en realidad no he probado:

public static T[] RemoveAt<T>(this T[] source, int index) { T[] dest = new T[source.Length - 1]; if( index > 0 ) Array.Copy(source, 0, dest, 0, index); if( index < source.Length - 1 ) Array.Copy(source, index + 1, dest, index, source.Length - index - 1); return dest; }

Y úsalo como:

Foo[] bar = GetFoos(); bar = bar.RemoveAt(2);


Solución LINQ de una línea:

myArray = myArray.Where((source, index) => index != 1).ToArray();

El 1 en ese ejemplo es el índice del elemento a eliminar, en este ejemplo, según la pregunta original, el segundo elemento (siendo 1 el segundo elemento en la indexación de matriz basada en cero de C #).

Un ejemplo más completo:

string[] myArray = { "a", "b", "c", "d", "e" }; int indexToRemove = 1; myArray = myArray.Where((source, index) => index != indexToRemove).ToArray();

Después de ejecutar ese fragmento, el valor de myArray será { "a", "c", "d", "e" } .


Utilizo este método para eliminar un elemento de una matriz de objetos. En mi situación, mis arreglos son de poca longitud. Entonces, si tiene matrices grandes, es posible que necesite otra solución.

private int[] RemoveIndices(int[] IndicesArray, int RemoveAt) { int[] newIndicesArray = new int[IndicesArray.Length - 1]; int i = 0; int j = 0; while (i < IndicesArray.Length) { if (i != RemoveAt) { newIndicesArray[j] = IndicesArray[i]; j++; } i++; } return newIndicesArray; }


Primer paso
Necesita convertir la matriz en una lista, puede escribir un método de extensión como este

// Convert An array of string to a list of string public static List<string> ConnvertArrayToList(this string [] array) { // DECLARE a list of string and add all element of the array into it List<string> myList = new List<string>(); foreach( string s in array){ myList.Add(s); } return myList; }

Segundo paso
Escriba un método de extensión para convertir de nuevo la lista en una matriz

// convert a list of string to an array public static string[] ConvertListToArray(this List<string> list) { string[] array = new string[list.Capacity]; array = list.Select(i => i.ToString()).ToArray(); return array; }

Últimos pasos
Escriba su método final, pero recuerde eliminar el elemento en el índice antes de convertir de nuevo a una matriz como el código show

public static string[] removeAt(string[] array, int index) { List<string> myList = array.ConnvertArrayToList(); myList.RemoveAt(index); return myList.ConvertListToArray(); }

ejemplos de códigos que se pueden encontrar en mi blog , seguir el seguimiento.


private int[] removeFromArray(int[] array, int id) { int difference = 0, currentValue=0; //get new Array length for (int i=0; i<array.Length; i++) { if (array[i]==id) { difference += 1; } } //create new array int[] newArray = new int[array.Length-difference]; for (int i = 0; i < array.Length; i++ ) { if (array[i] != id) { newArray[currentValue] = array[i]; currentValue += 1; } } return newArray; }