Tengo una matriz X de 10 elementos. Me gustaría crear una nueva matriz que contenga todos los elementos de X que comienzan en el índice 3 y terminan en el índice 7. Claro que puedo escribir fácilmente un bucle que lo hará por mí, pero me gustaría mantener mi código lo más limpio posible . ¿Hay algún método en C # que pueda hacerlo por mí?
Algo así (pseudocódigo):
Array NewArray = oldArray.createNewArrayFromRange(int BeginIndex , int EndIndex)
Array.Copy
no se ajusta a mis necesidades . Necesito que los elementos de la nueva matriz sean clones. Array.copy
es solo un memcpy
equivalente de C-Style , no es lo que estoy buscando.
Respuestas:
Puede agregarlo como un método de extensión:
Actualizar la clonación (que no era obvio en la pregunta original). Si realmente quieres un clon profundo; algo como:
Sin embargo, esto requiere que los objetos sean serializables (
[Serializable]
oISerializable
). Desde aquí se puede sustituir a cualquier otro serializador en su caso -XmlSerializer
,DataContractSerializer
, protobuf-net, etc.Tenga en cuenta que el clon profundo es complicado sin serialización; en particular,
ICloneable
es difícil de confiar en la mayoría de los casos.fuente
Puede usar
Array.Copy(...)
para copiar en la nueva matriz después de haberla creado, pero no creo que haya un método que cree la nueva matriz y copie una variedad de elementos.Si está utilizando .NET 3.5, podría usar LINQ:
pero eso será algo menos eficiente.
Vea esta respuesta a una pregunta similar para opciones para situaciones más específicas.
fuente
¿Has considerado usar
ArraySegment
?http://msdn.microsoft.com/en-us/library/1hsbd92d.aspx
fuente
IEnumerable<T>
y una variedad de otras interfaces útiles.ArraySegment
para responder la pregunta original?IList<T> newArray = (IList<T>)new ArraySegment<T>(oldArray, beginIndex, endIndex);
Veo que quieres hacer clonación, no solo copiar referencias. En este caso, puede usar
.Select
para proyectar miembros de la matriz en sus clones. Por ejemplo, si sus elementos se implementaronIClonable
, podría hacer algo como esto:Nota: Esta solución requiere .NET Framework 3.5.
fuente
IEnumerable
. Puedo obtener unaIEnumerable
,IList
,IArray
, etc ... con un mínimo esfuerzo, en línea si necesito. Si no necesito la copia profunda, simplemente elimino elSelect
. CaerSkip
oTake
me permite controlar el rango. Alternativamente, puedo mezclarlo conSkipWhile
y / oTakeWhile
.El siguiente código lo hace en una línea:
fuente
En C # 8 han introducido un nuevo
Range
yIndex
tipofuente
fuente
Basándose en la respuesta de Marc pero agregando el comportamiento de clonación deseado
Y si implementar ICloneable se parece demasiado al trabajo duro, uno reflexivo usando la biblioteca Copiable de Håvard Stranden para hacer el trabajo pesado requerido.
Tenga en cuenta que la implementación OX.Copyable funciona con cualquiera de:
Entonces esto debería cubrir casi cualquier situación que tenga. Si está clonando objetos en los que el gráfico secundario contiene elementos como conexiones db o identificadores de archivo / secuencia, obviamente tiene problemas, pero es cierto para cualquier copia profunda generalizada.
Si desea utilizar algún otro enfoque de copia profunda, este artículo enumera varios otros, por lo que le sugiero que no intente escribir el suyo.
fuente
Puedes hacer esto bastante fácil;
fuente
Creo que el código que estás buscando es:
Array.Copy(oldArray, 0, newArray, BeginIndex, EndIndex - BeginIndex)
fuente
Como alternativa a la copia de los datos, puede crear un contenedor que le dé acceso a una parte de la matriz original como si fuera una copia de la parte de la matriz. La ventaja es que no obtiene otra copia de los datos en la memoria, y el inconveniente es una ligera sobrecarga al acceder a los datos.
Uso:
fuente
Array.ConstrainedCopy funcionará.
fuente
No hay un método único que haga lo que quieras. Deberá poner a disposición un método de clonación para la clase en su matriz. Entonces, si LINQ es una opción:
fuente
¿Qué hay de usar Array.ConstrainedCopy :
A continuación se muestra mi publicación original. No funcionará
Puedes usar Array.CopyTo :
fuente
Qué tal esto:
Luego debe implementar la interfaz ICloneable en todas las clases en las que necesita usar esto, pero eso debería hacerlo.
fuente
No estoy seguro de cuán profundo es realmente, pero:
MyArray.ToList<TSource>().GetRange(beginningIndex, endIndex).ToArray()
Es un poco de sobrecarga, pero podría eliminar un método innecesario.
fuente
C # 8 ha proporcionado una función llamada como Rango para obtener subarreglos desde el índice inicial hasta el final. Puedes usarlo así.
fuente
En cuanto a la clonación, no creo que la serialización llame a sus constructores. Esto puede romper invariantes de clase si estás haciendo cosas interesantes en el ctor's.
Parece que la apuesta más segura son los métodos de clonación virtual que llaman constructores de copias.
fuente
La clonación de elementos en una matriz no es algo que se pueda hacer de manera universal. ¿Desea una clonación profunda o una copia simple de todos los miembros?
Vayamos al enfoque del "mejor esfuerzo": clonar objetos usando la interfaz ICloneable o la serialización binaria:
Esta no es una solución perfecta, porque simplemente no hay ninguna que funcione para cualquier tipo de objeto.
fuente
Puedes tomar clases hechas por Microsoft:
y entonces
fuente
Esta es la forma óptima, encontré, de hacer esto:
¡Espero eso ayude!
fuente
utilice el método de extensión:
y puedes usarlo
fuente
Código del System.Private.CoreLib.dll:
fuente
No cumple con su requisito de clonación, pero parece más simple que muchas respuestas:
fuente
fuente