Does anyone know of an efficient way to flatten a 2d array (non-jagged) in C# to a 1d and back again. I know in the back end C# must hold onto it as a 1d array I would just
Well, the object itself isn't a byte[]
, even though it's got the data itself in one contiguous block of memory. Don't forget that an array knows its ranks and lengths etc as well.
However, you can use Buffer.BlockCopy to copy the array quickly. For example:
byte[,] source = new byte[5,5];
byte[] dest = new byte[source.Length];
Buffer.BlockCopy(source, 0, dest, 0, source.Length);
Note that the final argument is the number of bytes, not the number of array elements.
var myFlattenedByteArray = my2DByteArray.SelectMany(b=>b).ToArray();
This will return each element of each subarray of the 2D byte array in subarray-element order: myFlattenedByteArray[1] == my2DByteArray[0][1]. There are probably more performant or efficient solutions (especially the slupring of the Enumerable produced by SelectMany into its own Array) but it's a one-liner.
You can't get a managed byte[]
array from a byte[,]
without copying it out (not that I know of, anyway).
If you're comfortable with unsafe
code you can fix a byte*
on the array and I believe that should work:
fixed (byte* ptr = array)
{
for (int i = 0; i < N; ++i)
{
byte b = ptr[i];
// Do whatever you need.
}
}
To go from a 2D index to 1D index:
int i = y * width + x;
And back:
int x = i % width;
int y = i / width;
Then the simplest is to just iterate over your array, copying the values one by one.