12

I find myself converting 1D byte and single arrays to 2D by doing the following. I suspect it is probably as fast as other methods, but perhaps there is a cleaner simpler paradigm? (Linq?)

    private static byte[,] byte2D(byte[] input, int height, int width)
    {
        byte[,] output = new byte[height, width];
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                output[i, j] = input[i * width + j];
            }
        }
        return output;
    }

    private static Single[,] single2D(byte[] input, int height, int width)
    {
        Single[,] output = new Single[height, width];
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                output[i, j] = (Single)input[i * width + j];
            }
        }
        return output;
    }
2
  • Your second method, is the type of input supposed to be byte[]? Commented Jan 23, 2015 at 15:21
  • Can you provide sample input/output for one of those functions? Commented Jan 23, 2015 at 15:23

4 Answers 4

14

This doesn't help with making the code inside the methods cleaner, but I noticed that you have 2 basically identical methods that differ only in their types. I suggest using generics.

This would let you define your method only once. Using the where keyword, you can even limit the kind of types you allow your method to work on.

private static T[,] Make2DArray<T>(T[] input, int height, int width)
{
    T[,] output = new T[height, width];
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            output[i, j] = input[i * width + j];
        }
    }
    return output;
}

You would call this method like this

int[] a;  //or any other array.
var twoDArray = Make2DArray(a, height, width);
Sign up to request clarification or add additional context in comments.

2 Comments

Buffer.BlockCopy() is faster and simpler. Been around since Framework 1.1
@dynamichael only works though if your type actually has a constant size in bytes .. wouldn't work e.g. for string
7

Buffer.BlockCopy(input, 0, output, 0, input.Length); is faster, but fastest is to not copy the array at all.

If you don't really need a separate 2D array, you can just access your 1D array like a 2D array trough a function, property, or custom type. For example:

class D2<T> {
    T[] input;
    int lenght0;
    public d2(T[] input, int lenght0) {
        this.input = input;
        this.lenght0 = lenght0;
    }
    public T this[int index0, int index1] {
        get { return input[index0 * this.lenght0 + index1]; }
        set { input[index0 * this.lenght0 + index1] = value; }
    }
}

...

byte[] input = { 1, 2, 3, 4 };
var output = new D2<byte>(input, 2);
output[1, 1] = 0;  // now input is { 1, 2, 3, 0 };

Also, in .NET access to multidimensional arrays is a bit slower than access to jagged arrays

1 Comment

Buffer.BlockCopy seems only to work for arrays based on primitive types, not e.g. object[].
2

Generic function:

private static b[,] to2D<a, b>(a source, valueAt: Func<a, int, b>, int height, int width)
{
    var result = new b[height, width];
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            result[i, j] = valueAt(source, i * width + j);
        }
    }
    return result;
}

var bytes = to2D<byte[], byte>([], (bytes, at) => bytes[at], 10, 20);

Comments

2

I know I am late to the party, but if you want to access a 1d array, list, etc. like it were an n-dimensional array (without copying) you can use https://github.com/henon/SliceAndDice to do so without copying.

// create a 2D array of bytes from a byte[]
var a = new ArraySlice<byte>( new byte[100], new Shape(10,10));
// now access with 2d coordinates
a[7,9]=(byte)56;

Of course, everyone can do it for simple 2d, 3d, ... nd volumes easily. But this lib also allows to do slicing of n-dimensional arrays without copying.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.