Array.Copy 是否适用于多维数组?

发布于 2024-12-02 13:03:17 字数 491 浏览 1 评论 0原文

这段代码工作正常:

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];

但我没有太多运气将其替换为 Array.Copy。基本上,如果调整大小的数组更大,它只会在边缘添加空白矩形。如果它较小,那么它应该只切掉边缘。

执行此操作时:

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

它会弄乱数组,其所有内容都会变得无序,并且不会保留其原始索引。也许我只是脑子有病什么的?

This code works fine:

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];

But I am not having much luck replacing it with Array.Copy. Basically, if the resized array is larger it just adds blank rectangles to the edges. If it is smaller then it should just cut off the edges.

When doing this:

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

It messes up the array and all of its contents become disordered and do not retain their original index. Maybe I'm just having a brainfart or something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

少钕鈤記 2024-12-09 13:03:17

是的。然而,它并不像你想象的那样工作。相反,它将每个多维数组视为一个单维数组(这实际上是它们在内存中的样子,这只是一个技巧,让我们在它们之上放置一些结构以将它们视为多维),然后复制单个数组维度结构。因此,如果您有

1 2 3
4 5 6

并且想要将其复制到其中

x x x x
x x x x

,那么它将认为第一个数组为

1 2 3 4 5 6

,第二个数组为

x x x x x x x x

,结果将是

1 2 3 4 5 6 x x

,您将看到“

1 2 3 4
5 6 x x

明白了吗?”

Yes. However, it doesn't work the way you are thinking it works. Rather, it thinks of each mutlidimensional array as a single-dimensional array (which is actually what they are in memory, it's just a trick that lets us place some structure on top of them to think of them as multidimensional) and then copies the single-dimensional structures. So if you have

1 2 3
4 5 6

and want to copy it into

x x x x
x x x x

then it will think of the first array as

1 2 3 4 5 6

and the second as

x x x x x x x x

and the result will be

1 2 3 4 5 6 x x

which will appear to you as

1 2 3 4
5 6 x x

Got it?

放我走吧 2024-12-09 13:03:17

我使用这段代码:

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;

}

像这样调用字符串数组

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

I use this 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;

}

calling like this for array of strings

ResizeBidimArrayWithElements<string>(ref arrayOrigin, vNumRows, vNumCols);
墟烟 2024-12-09 13:03:17

我需要在下一次中断命中之前消耗缓冲区中的数据并复制到大型保存数组。循环复制不是一个选择;太慢了。在完成所有复制之前,我不需要组合数据的多维结构,这意味着我可以 Buffer.BlockCopy() 到一维数组,然后再次复制到多维数组以获得所需的结构。这里有一些代码(在控制台中运行)将演示该技术以及性能。

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

输出:

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

I had a need to consume data from a buffer and copy off to a large holding array before the next interrupt hit. Copying in a loop wasn't an option; far too slow. I didn't need the multidimensional structure of the combined data until all of the copying was done, this meant I could Buffer.BlockCopy() to a single dimension array, then copy again onto a multidimensional array to obtain the required structure. Here's some code (run it in a console) that will demonstrate the technique as well as the performance.

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

Output:

BlockCopy to flat array took 14 ms
BlockCopy to 2 dimensional array took 28 ms
Loop-copy to 2 dimensional array took 149 ms
莳間冲淡了誓言ζ 2024-12-09 13:03:17

简单地使用“Clone()”函数,如下所示:

这是您的数组列表

object newArray = new object [row, column];

当您创建另一个数组时,只需使用以下代码:

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

简单!玩得开心!

Simple use the "Clone()" function like the following:

This is your array list

object newArray = new object [row, column];

When you are creating another Array just use this code:

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

Simple! Have fun!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文