Работает ли Array.Copy с многомерными массивами?
Этот код отлично работает:
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);
Он испортил массив, и все его содержимое стало неупорядоченным и не сохранили свой первоначальный индекс. Может быть, у меня просто мозг или что-то еще?
Ответы
Ответ 1
Да. Однако, это не работает так, как вы думаете, что это работает. Скорее, он думает о каждом многомерном массиве как о одномерном массиве (который на самом деле находится в памяти, это всего лишь трюк, который позволяет нам помещать некоторую структуру поверх них, чтобы думать о них как о многомерном), а затем копирует одиночный -мерные структуры. Поэтому, если у вас есть
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
Получил?
Ответ 2
Я использую этот код:
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);
Ответ 3
Мне пришлось потреблять данные из буфера и копировать их на большой массив до следующего прерывания. Копирование в цикле не было возможным; слишком медленно. Мне не нужна многомерная структура комбинированных данных, пока все копии не были выполнены, это означало, что я мог 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
Ответ 4
Просто используйте функцию "Clone()" следующим образом:
Это ваш список массивов
object newArray = new object [row, column];
Когда вы создаете другой массив, просто используйте этот код:
object[,] clonedArray = (object[,]) newArray.Clone();
Просто! Повеселись!