web-dev-qa-db-fra.com

Array.Copy fonctionne-t-il avec des tableaux multidimensionnels?

Ce code fonctionne bien:

var newArray = new Rectangle[newHeight, newWidth];

for (int x = 0; x < newWidth; x++)
    for (int y = 0; y < newHeight; y++)
        newArray[y, x] = (x >= width) || (y >= height) ? Rectangle.Empty : tiles[y, x];

Mais je n'ai pas beaucoup de chance de le remplacer par Array.Copy. Fondamentalement, si le tableau redimensionné est plus grand, il ne fait qu'ajouter des rectangles vierges aux bords. S'il est plus petit, il devrait simplement couper les bords.

En faisant ceci:

Array.Copy(tiles, newArray, newWidth * newHeight);

Il gâche le tableau et tout son contenu devient désordonné et ne conserve pas son index d'origine. Peut-être que je suis juste avoir un brainfart ou quelque chose?

22
Andrew Godfrey

Oui. Cependant, cela ne fonctionne pas comme vous le pensez. Plutôt, il considère chaque tableau multidimensionnel comme un tableau unidimensionnel (ce qui est en fait ce qu’ils sont en mémoire, c’est juste un truc qui nous permet de placer une structure sur eux pour les considérer comme multidimensionnels), puis copie le fichier unique. structures tridimensionnelles. Donc si vous avez

1 2 3
4 5 6

et que vous voulez le copier dans

x x x x
x x x x

alors il va penser au premier tableau comme

1 2 3 4 5 6

et le second comme

x x x x x x x x

et le résultat sera

1 2 3 4 5 6 x x

qui vous apparaîtra comme

1 2 3 4
5 6 x x

Je l'ai?

30
jason

J'utilise ce code:

public static void ResizeBidimArrayWithElements<T>(ref T[,] original, int rows, int cols)
{

    T[,] newArray = new T[rows, cols];
    int minX = Math.Min(original.GetLength(0), newArray.GetLength(0));
    int minY = Math.Min(original.GetLength(1), newArray.GetLength(1));

    for (int i = 0; i < minX; ++i)
        Array.Copy(original, i * original.GetLength(1), newArray, i * newArray.GetLength(1), minY);

    original = newArray;

}

appelant comme ça pour un tableau de chaînes

ResizeBidimArrayWithElements<string>(ref arrayOrigin, vNumRows, vNumCols);
6
Biggum

J'avais besoin de consommer les données d'un tampon et de les copier dans un grand groupe de stockage avant le prochain coup d'interruption. Copier en boucle n'était pas une option. beaucoup trop lent. Je n'avais pas besoin de la structure multidimensionnelle des données combinées jusqu'à ce que toute la copie soit terminée. Cela signifiait que je pouvais Buffer.BlockCopy () dans un tableau à une seule dimension, puis copier à nouveau sur un tableau multidimensionnel pour obtenir les informations requises. structure. Voici un code (exécuté dans une console) qui illustrera la technique ainsi que les performances.

static class Program
{
    [STAThread]
    static void Main()
    {
        Stopwatch watch = new Stopwatch();

        const int width = 2;
        const int depth = 10 * 1000000;

        //  Create a large array of data
        Random r = new Random(100);
        int[,] data = new int[width, depth];
        for(int i = 0; i < width; i++)
        {
            for(int j = 0; j < depth; j++)
            {
                data[i, j] = r.Next();
            }
        }

        //  Block copy to a single dimension array
        watch.Start();
        int[] buffer = new int[width * depth];
        Buffer.BlockCopy(data, 0, buffer, 0, data.Length * sizeof(int));
        watch.Stop();
        Console.WriteLine("BlockCopy to flat array took {0}", watch.ElapsedMilliseconds);

        //  Block copy to multidimensional array
        int[,] data2 = new int[width, depth];
        watch.Start();
        Buffer.BlockCopy(buffer, 0, data2, 0,buffer.Length * sizeof(int));
        watch.Stop();
        Console.WriteLine("BlockCopy to 2 dimensional array took {0}", watch.ElapsedMilliseconds);


        //  Now try a loop based copy - eck!
        data2 = new int[width, depth];
        watch.Start();
        for (int i = 0; i < width; i++)
        {
            for (int j = 0; j < depth; j++)
            {
                data2[i, j] = data[i, j];
            }
        }
        watch.Stop();
        Console.WriteLine("Loop-copy to 2 dimensional array took {0} ms", watch.ElapsedMilliseconds);
    }
}

Sortie:

BlockCopy to flat array took 14 ms
BlockCopy to 2 dimensional array took 28 ms
Loop-copy to 2 dimensional array took 149 ms
2
Steve K

Utilisez simplement la fonction "Clone ()" comme suit:

Ceci est votre liste de tableau

object newArray = new object [row, column];

Lorsque vous créez un autre tableau, utilisez simplement ce code:

object[,] clonedArray = (object[,]) newArray.Clone();

Simple! S'amuser!