Uso System.Collections.ObjectModel.Collection<Foo>.
abatishchev
1
Para mi juego, elegí una estructura de datos "nulo en el índice". Básicamente, la matriz interna (buffer) es de tamaño estático, y en lugar de eliminar el índice y cambiar el tamaño de la matriz, simplemente hago que el índice sea nulo. Cuando necesito agregar un elemento, solo encuentro el primer índice no nulo y lo coloco allí. Funciona bastante bien, pero obviamente no para todo.
Krythic
Respuestas:
202
Si no quieres usar la Lista:
var foos =newList<Foo>(array);
foos.RemoveAt(index);return foos.ToArray();
Podrías probar este método de extensión que no he probado:
publicstatic 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;}
El primer ejemplo dado en esta respuesta es mucho menos eficiente que el segundo. Requiere dos copias de matriz y un cambio de todo después del índice en lugar de una copia de matriz selectiva.
Martin Brown
2
+1, por supuesto, pero también podemos usar la lista OR O List <Foo> list = new List <Foll> (GetFoos ()); list.Remove (my_foo); list.RemoveAt (2); donde GetFoos () devolverá la matriz de Foos !!!!
shahjapan
2
La primera línea dentro del método debería decir 'source.Length' en lugar de 'array.Length'.
Nelson
1
Además, tenga en cuenta que cualquier variable que almacene una referencia a la matriz original continuará conteniendo los datos originales y que cualquier comparación de igualdad de referencia entre la matriz en la fuente y la matriz de salida devolverá un valor negativo.
bkqc
1
@MartinBrown En realidad, la conversión de una lista a \ from y array es mucho más lenta que una copia de array (que puede copiar los datos a la velocidad máxima permitida por la CPU con solo unas pocas instrucciones ASM). Además, cambiar una lista es muy rápido porque solo se trata de intercambiar algunos punteros y eliminar los datos del nodo (que en este caso son solo 8 bytes [más otros 16 para los punteros head / tail]).
krowe2
66
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 corta y copiar los elementos antiguos a la nueva matriz, excluyendo el elemento que desea eliminar.
Por lo tanto, probablemente sea mejor usar una Lista en lugar de una matriz.
Convierta el conjunto en una listaList<mydatatype> array = new List<mydatatype>(arrayofmydatatype)
Immortal Blue
1
@ImmortalBlue o simplemente var myList = myArray.ToList();usando el Enumerable.ToList()método del System.Linqespacio de nombres.
Dyndrilliac
58
Yo uso este método para eliminar un elemento de una matriz de objetos. En mi situación, mis matrices son pequeñas en longitud. Entonces, si tiene matrices grandes, es posible que necesite otra solución.
Personalmente, me gusta esta respuesta mejor que la respuesta aceptada. Debe ser igual de eficiente y es mucho más fácil de leer. Puedo mirarlo y saber que es correcto. Tendría que probar el otro para asegurarme de que esas copias se escribieron correctamente.
Oillio
1
Realmente es una pena que esta respuesta sea tan baja, cuando es mucho mejor que las dos anteriores.
Sepulcritud
¡Aaarhg, esa es la respuesta que estaba buscando! Este es el mejor método sin listas.
Jordi Huertas
47
Solución de una línea LINQ:
myArray = myArray.Where((source, index)=> index !=1).ToArray();
El 1en ese ejemplo es el índice del elemento a eliminar: en este ejemplo, según la pregunta original, el segundo elemento ( 1siendo el segundo elemento en la indexación de matriz basada en C # cero).
Para áreas que requieren acceso frecuente / de alto rendimiento, no se recomienda LINQ.
Krythic
3
@Krythic Ese es un comentario justo. Ejecutado miles de veces en un ciclo cerrado, el rendimiento de esta solución no es tan bueno como algunas de las otras soluciones altamente votadas en esta página: dotnetfiddle.net/z9Xkpn
Jon Schneider
9
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>:
publicstaticvoidRemoveAt<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 oneArray.Resize(ref arr, arr.Length-1);}
"sin copiar a otra matriz" - por la documentación vinculada, Array.Resize realidad hace asignar una nueva matriz detrás de las escenas, y copia los elementos de la matriz de edad a la nueva. Aún así, me gusta la concisión de esta solución.
Jon Schneider
Muy bonito y claro si estás seguro de que es una matriz relativamente pequeña.
Darren
1
Continuando el comentario de @ JonSchneider, no es "la misma instancia de matriz". Es por eso que debes usar refcuando llamas al Resizemétodo. La longitud de una instancia de matriz es fija e inmutable.
Jeppe Stig Nielsen
2
Si el orden de los elementos no es importante, en lugar de mover todos los elementos hacia abajo, puede intercambiar el elemento en el índice con el último elemento y luego cambiar el tamaño: arr [index] = arr [arr.Length - 1]; Array.Resize (ref arr, arr.Length - 1);
Bartel
5
Aquí hay una versión anterior que tengo que funciona en la versión 1.0 del marco .NET y no necesita tipos genéricos.
publicstaticArrayRemoveAt(Array source,int index){if(source ==null)thrownewArgumentNullException("source");if(0> index || index >= source.Length)thrownewArgumentOutOfRangeException("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í:
classProgram{staticvoidMain(string[] args){string[] x =newstring[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]);}}
publicstaticElementDefinitionImpl[]RemoveElementDefAt(ElementDefinition[] oldList,int removeIndex
){ElementDefinitionImpl[] newElementDefList =newElementDefinitionImpl[ oldList.Length-1];int offset =0;for(int index =0; index < oldList.Length; index++){ElementDefinitionImpl elementDef = oldList[ index ]asElementDefinitionImpl;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;}
En una matriz normal, debe mezclar todas las entradas de la matriz por encima de 2 y luego cambiar su tamaño utilizando el método Cambiar tamaño. Puede que sea mejor usar una ArrayList.
Aquí hay una pequeña colección de métodos auxiliares que produje en base a algunas de las respuestas existentes. Utiliza tanto extensiones como métodos estáticos con parámetros de referencia para la máxima idealidad:
publicstaticclassArr{publicstaticintIndexOf<TElement>(thisTElement[]Source,TElementElement){for(var i =0; i <Source.Length; i++){if(Source[i].Equals(Element))return i;}return-1;}publicstaticTElement[]Add<TElement>(refTElement[]Source,paramsTElement[]Elements){varOldLength=Source.Length;Array.Resize(refSource,OldLength+Elements.Length);for(int j =0,Count=Elements.Length; j <Count; j++)Source[OldLength+ j]=Elements[j];returnSource;}publicstaticTElement[]New<TElement>(paramsTElement[]Elements){returnElements??newTElement[0];}publicstaticvoidRemove<TElement>(refTElement[]Source,paramsTElement[]Elements){foreach(var i inElements)RemoveAt(refSource,Source.IndexOf(i));}publicstaticvoidRemoveAt<TElement>(refTElement[]Source,intIndex){varResult=newTElement[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 al rendimiento, es decente, pero probablemente podría mejorarse. Removese basa IndexOfy se crea una nueva matriz para cada elemento que desea eliminar llamando RemoveAt.
IndexOfes el único método de extensión ya que no necesita devolver la matriz original. Newacepta múltiples elementos de algún tipo para producir una nueva matriz de dicho tipo. Todos los demás métodos deben aceptar la matriz original como referencia, por lo que no es necesario asignar el resultado después, ya que eso ya ocurre internamente.
Hubiera definido un Mergemétodo para fusionar dos matrices; sin embargo, eso ya se puede lograr con el Addmétodo pasando una matriz real frente a múltiples elementos individuales. Por lo tanto, Addse puede usar de las dos formas siguientes para unir dos conjuntos de elementos:
Sé que este artículo tiene diez años y, por lo tanto, probablemente esté muerto, pero esto es lo que intentaría hacer:
Use el método IEnumerable.Skip (), que se encuentra en System.Linq . Saltará el elemento seleccionado de la matriz y devolverá otra copia de la matriz que solo contiene todo excepto el objeto seleccionado. Luego repita eso para cada elemento que desee eliminar y luego guárdelo en una variable.
Por ejemplo, si tenemos una matriz llamada "Muestra" (de tipo int []) con 5 números. Queremos eliminar el segundo, así que intenta "Sample.Skip (2);" debería devolver la misma matriz, excepto sin el segundo número.
¿Este método no pasa por alto un número específico de elementos en una secuencia y luego devuelve los elementos restantes ? En su ejemplo, "omitirá" los dos primeros elementos de la lista genérica y no solo el segundo.
xnr_z
-4
Primer paso
Necesitas convertir la matriz en una lista, puedes escribir un método de extensión como este
// Convert An array of string to a list of stringpublicstaticList<string>ConnvertArrayToList(thisstring[]array){// DECLARE a list of string and add all element of the array into itList<string> myList =newList<string>();foreach(string s inarray){
myList.Add(s);}return myList;}
Segundo paso
Escriba un método de extensión para volver a convertir la lista en una matriz
// convert a list of string to an array publicstaticstring[]ConvertListToArray(thisList<string>list){string[]array=newstring[list.Capacity];array=list.Select(i => i.ToString()).ToArray();returnarray;}
Últimos pasos
Escriba su método final, pero recuerde eliminar el elemento en el índice antes de volver a convertirlo en una matriz como se muestra en el código
System.Collections.ObjectModel.Collection<Foo>
.Respuestas:
Si no quieres usar la Lista:
Podrías probar este método de extensión que no he probado:
Y úsalo como:
fuente
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 corta y copiar los elementos antiguos a la nueva matriz, excluyendo el elemento que desea eliminar.
Por lo tanto, probablemente sea mejor usar una Lista en lugar de una matriz.
fuente
List<mydatatype> array = new List<mydatatype>(arrayofmydatatype)
var myList = myArray.ToList();
usando elEnumerable.ToList()
método delSystem.Linq
espacio de nombres.Yo uso este método para eliminar un elemento de una matriz de objetos. En mi situación, mis matrices son pequeñas en longitud. Entonces, si tiene matrices grandes, es posible que necesite otra solución.
fuente
Solución de una línea LINQ:
El
1
en ese ejemplo es el índice del elemento a eliminar: en este ejemplo, según la pregunta original, el segundo elemento (1
siendo el segundo elemento en la indexación de matriz basada en C # cero).Un ejemplo más completo:
Después de ejecutar ese fragmento, el valor de
myArray
será{ "a", "c", "d", "e" }
.fuente
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>
:fuente
ref
cuando llamas alResize
método. La longitud de una instancia de matriz es fija e inmutable.Aquí hay una versión anterior que tengo que funciona en la versión 1.0 del marco .NET y no necesita tipos genéricos.
Esto se usa así:
fuente
No es exactamente la forma de hacerlo, pero si la situación es trivial y usted valora su tiempo, puede intentar esto para los tipos anulables.
y luego verifique si hay entradas nulas en su lógica.
fuente
Como de costumbre, llego tarde a la fiesta ...
Me gustaría agregar otra opción a la lista de buenas soluciones ya presentes. =)
Vería esto como una buena oportunidad para Extensiones.
Referencia: http://msdn.microsoft.com/en-us/library/bb311042.aspx
Entonces, definimos alguna clase estática y en ella, nuestro Método.
Después de eso, podemos usar nuestro método extendido willy-nilly. =)
fuente
Pruebe el siguiente código:
o
fuente
Así es como lo hice ...
fuente
En una matriz normal, debe mezclar todas las entradas de la matriz por encima de 2 y luego cambiar su tamaño utilizando el método Cambiar tamaño. Puede que sea mejor usar una ArrayList.
fuente
fuente
Aquí hay una pequeña colección de métodos auxiliares que produje en base a algunas de las respuestas existentes. Utiliza tanto extensiones como métodos estáticos con parámetros de referencia para la máxima idealidad:
En cuanto al rendimiento, es decente, pero probablemente podría mejorarse.
Remove
se basaIndexOf
y se crea una nueva matriz para cada elemento que desea eliminar llamandoRemoveAt
.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 la matriz original como referencia, por lo que no es necesario asignar el resultado después, ya que eso ya ocurre internamente.Hubiera definido un
Merge
método para fusionar dos matrices; sin embargo, eso ya se puede lograr con elAdd
método pasando 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:O
fuente
Sé que este artículo tiene diez años y, por lo tanto, probablemente esté muerto, pero esto es lo que intentaría hacer:
Use el método IEnumerable.Skip (), que se encuentra en System.Linq . Saltará el elemento seleccionado de la matriz y devolverá otra copia de la matriz que solo contiene todo excepto el objeto seleccionado. Luego repita eso para cada elemento que desee eliminar y luego guárdelo en una variable.
Por ejemplo, si tenemos una matriz llamada "Muestra" (de tipo int []) con 5 números. Queremos eliminar el segundo, así que intenta "Sample.Skip (2);" debería devolver la misma matriz, excepto sin el segundo número.
fuente
Primer paso
Necesitas convertir la matriz en una lista, puedes escribir un método de extensión como este
Segundo paso
Escriba un método de extensión para volver a convertir la lista en una matriz
Últimos pasos
Escriba su método final, pero recuerde eliminar el elemento en el índice antes de volver a convertirlo en una matriz como se muestra en el código
ejemplos de códigos se pueden encontrar en mi blog , sigue el seguimiento.
fuente
.ToArray()
y unList<T>
constructor que tiene una secuencia existente ...