2009-04-28 13 views
13

Tenemos el objeto siguienteCómo copiar una fila de valores de una matriz 2D a una matriz 1D?

int [,] oGridCells; 

que sólo se utiliza con un primer índice fijo

int iIndex = 5; 
for (int iLoop = 0; iLoop < iUpperBound; iLoop++) 
{ 
    //Get the value from the 2D array 
    iValue = oGridCells[iIndex, iLoop]; 

    //Do something with iValue 
} 

¿Hay alguna manera en .NET para convertir los valores en un primer índice fijo en una sola dimensión array (que no sea mediante el bucle de los valores)?

Dudo que acelere el código (y puede hacerlo más lento) si la matriz solo se está bucleando una vez. Pero si la matriz estaba siendo fuertemente manipulada, una matriz de una sola dimensión sería más eficiente que una matriz de múltiples dimensiones.

Mi razón principal para hacer la pregunta es para ver si se puede hacer y cómo, en lugar de usarla para el código de producción.

Respuesta

25

El siguiente código muestra la copia de 16 bytes (4 ints) de una matriz 2-D a una matriz 1-D.

int[,] oGridCells = {{1, 2}, {3, 4}}; 
int[] oResult = new int[4]; 
System.Buffer.BlockCopy(oGridCells, 0, oResult, 0, 16); 

También puede copiar selectivamente solo 1 fila de la matriz proporcionando los desplazamientos de bytes correctos. Este ejemplo copia la fila central de una matriz 2-D de 3 filas.

int[,] oGridCells = {{1, 2}, {3, 4}, {5, 6}}; 
int[] oResult = new int[2]; 
System.Buffer.BlockCopy(oGridCells, 8, oResult, 0, 8); 
+0

Esto no alcanza los resultados requeridos ya que copia todos los valores, no solo los valores del primer índice 0 o 1. – stevehipwell

+0

Agregué un ejemplo para copiar 1 fila. – BlueMonkMN

+0

Para usar este método necesitarás calcular los límites de la matriz para obtener el desplazamiento. Esto es ineficiente para matrices de múltiples dimensiones. Pero parece que funcionaría. – stevehipwell

0

Me sorprendería si fuera posible: apuesto oGridCells[iIndex, iLoop] es sólo una especie de taquigrafía (internamente, en MSIL) para oGridCells[iIndex * iLoop], y que las matrices multidimensionales son azúcar sintáctico para esto.

Para responder a su pregunta: No. Deberá repetir los valores.

+0

Son un tipo diferente a las matrices de dimensiones individuales. Una matriz de dimensión única de índice cero es un tipo de vector, mientras que todas las demás matrices son de tipo matriz. Entonces no la sintaxis de azúcar. – stevehipwell

2

Editar:

Me di cuenta de que hay una manera! De acuerdo, probablemente no valga la pena. Use unsafe code. Ejemplo completo, mostrando en ambos sentidos, con inseguro a continuación:

public class MultiSingleUnsafe 
{ 
    public static unsafe void Main(String[] a) 
    { 
    int rowCount = 6; 
    int iUpperBound = 10; 
    int [,] oGridCells = new int[rowCount, iUpperBound]; 

    int iIndex = rowCount - 2; // Pick a row. 

    for(int i = 0; i < iUpperBound; i++) 
    { 
     oGridCells[iIndex, i] = i; 
    } 

    for (int iLoop = 0; iLoop < iUpperBound; iLoop++) 
    { 
     //Get the value from the 2D array 
     int iValue = oGridCells[iIndex, iLoop]; 
     Console.WriteLine("Multi-dim array access iValue: " + iValue); 
     //Do something with iValue 
    } 

    fixed(int *lastRow = &(oGridCells[iIndex,0])) 
    { 
     for (int iLoop = 0; iLoop < iUpperBound; iLoop++) 
     { 
     int iValue = lastRow[iLoop]; 
     Console.WriteLine("Pointer access iValue: " + iValue); 
     } 
    } 
    } 
} 

No hay manera que conozco para emitir una matriz de múltiples dimensiones en una sola unidimensional en C#. Por supuesto, puede crear una nueva matriz unidimensional y copiar en ella. Pero no creo que esto obtenga un beneficio en el rendimiento incluso si revisa los valores varias veces. Como dijo Daren, internamente, es toda la aritmética del puntero de todos modos. Si quieres estar seguro, perfilalo.

+1

No estoy buscando un elenco, sé que eso no es posible. – stevehipwell

1

No se puede obtener una referencia para cada conjunto. Sin embargo, puede usar un jagged array.

+0

De acuerdo, si estuviera reescribiendo el código (que no es una opción) haría uso de arreglos dentados. Especialmente dado que las matrices dentadas tienen un rendimiento mejorado sobre las matrices de múltiples dimensiones. – stevehipwell

1

"Pero si la matriz estaba siendo manipulada en gran medida, una matriz de una sola dimensión sería más eficiente que una matriz de múltiples dimensiones".

Hice algunos perfiles de exactamente este último verano y me sorprendió no ver diferencias significativas en el rendimiento entre una matriz 2D y 1D.

No probé el rendimiento de una matriz dentada.

+0

Son tipos diferentes, ciertas operaciones (por ejemplo, probar la longitud) pueden ser significativamente más lentas. Una matriz dentada ofrece lo mejor de ambos mundos. – stevehipwell

1

puede probar esta:

int[,] twoD = new int[2,2]; 
twoD[0, 0] = 1; 
twoD[0, 1] = 2; 
twoD[1, 0] = 3; 
twoD[1, 1] = 4; 

int[] result = twoD.Cast<int>().Select(c => c).ToArray(); 

El resultado será una matriz de enteros con datos:

1, 2, 3, 4 
Cuestiones relacionadas