As far as I know, a 2-D array is laid out in memory exactly like a 1-D array, it just uses different indexing. So given that, it seems like there must be some way (probably unsafe) in C# to convert a 1-D array to a 2-D array without actually copying elements, assuming you want the elements from the 1-D array to translate to the 2-D array in a row-first manner. I did figure out how to accomplish this with a single copy command, but it still seems like more processing than is necessary:
int[] onedim = new int[] { 5, 3, 6, 2, 1, 5 };
int[,] twodim = new int[2, 3];
GCHandle pinnedArray = GCHandle.Alloc(twodim, GCHandleType.Pinned);
IntPtr pointer = pinnedArray.AddrOfPinnedObject();
Marshal.Copy(onedim, 0, pointer, onedim.Length);
pinnedArray.Free();
Is there some way that I could tell C#, treat this 1-D array as a 2-D array with these dimensions instead? Unsafe code is fine. If not, is this a limitation of the language or is there some fundamental problem I am missing?
One way would be to define a class that accesses the underlying 1D array
public class Array2D<T>
{
private readonly T[] _data;
private readonly Int32 _dimX;
private readonly Int32 _dimY;
public Array2D(T[] data, Int32 dimX, Int32 dimY)
{
_data = data;
_dimX = dimX;
_dimY = dimY;
}
public T this [Int32 x, Int32 y]
{
get { return _data[x * _dimY + y]; }
set { _data[x * _dimY + y] = value; }
}
}
var array = new[] { 1, 2, 3, 4, 5, 6 };
var array2d = new Array2D<Int32>(array, 2, 3);
Assert.AreEqual(array2d[0, 0], array[0]);
Assert.AreEqual(array2d[0, 1], array[1]);
Assert.AreEqual(array2d[0, 2], array[2]);
Assert.AreEqual(array2d[1, 0], array[3]);
Assert.AreEqual(array2d[1, 1], array[4]);
Assert.AreEqual(array2d[1, 2], array[5]);
My indexing might be backwards, however this wold behave like a 2D array while maintaining the 1D array reference.
edit: Indexing was backwards, fixed it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With