Convert byte[,] to byte[]
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 woul开发者_运维技巧d just like to get a handle on the back end 1d array if at all possible.
The reason why I would like to do this is because I would like to be able to in managed code have it as a 2d, at times I would like to hand it off as a 1d to unmanaged dll imported code (optimized assembly in digital image processing is a good example).
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.
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.
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.
精彩评论