views:

104

answers:

4

Hi,

I would like a function to convert a single dimension array int[480000] into a 2d array of size int[800,600]. Can you please help me how this can be done?

+1  A: 
for (int i = 0; i < 800; ++i) {
    for (int j = 0; j < 600; ++j) {
        m[i, j] = a[600*i + j];
    }
}

Depending on your storage layout, you might need to use i + 800*j instead.

Marcelo Cantos
j should be up to 600, of course :)
Thanks @smerriman. Thanks what I get for copy-pasting.
Marcelo Cantos
+5  A: 
public static T[,] Convert<T>(this T[] source, int rows, int columns)
{
  int i = 0;
  T[,] result = new T[rows, columns];

  for (int row = 0; row < rows; row++)
    for (int col = 0; col < columns; col++)
      result[row, col] = source[i++];
  return result;
}
Jaroslav Jandek
+1  A: 

UPD (fixed filling by column instead of by row, here is right version)

private static T[,] create2DimArray<T>(T[] array, int n)
        {
            if (n <= 0)
                throw new ArgumentException("Array M dimension cannot be less or equals zero","m");
            if (array == null)
                throw new ArgumentNullException("array", "Array cannot be null");
            if (array.Length == 0)
                throw new ArgumentException("Array cannot be empty", "array");

            int m = array.Length % n == 0 ? array.Length / n : array.Length / n + 1;
            var newArr = new T[m,n];
            for (int i = 0; i < arr.Length; i++)
            {
                int k = i / n;
                int l = i % n;
                newArr[k, l] = array[i];
            }

            return newArr;
        }

For 1000000 of elements it works 33 ms on my machine. Really fast with 1 for loop.

Eugene Cheverda
1) `arr.Length` -> `array.Length`. 2) Note: it will copy the array column by column, not row by row as you would usually expect.
Jaroslav Jandek
Sorry, was wrong. I've updated answer, I was mistaken in dimension sizes and indexex. In second parameter we pass number of columns we need, then we calculate rows count and fill new 2d array.
Eugene Cheverda
+5  A: 

Do you really want to physically move the data or would a 800x600 'View' be sufficient?
You could use a wrapper like this:

// error checking omitted
class MatrixWrapper<T>
{
    private T[] _data;
    private int _columns;

    public MatrixWrapper(T[] data, int rows, int columns)
    {
        _data = data;
        _columns = columns;
        // validate rows * columns == length
    }

    public T this[int r, int c]
    {
        get { return _data[Index(r, c)]; }
        set { _data[Index(r, c)] = value; }
    }

    private int Index(int r, int c)
    {
        return r * _columns + c;
    }
}

And you use it like:

        double[] data = new double[4800];
        var wrapper = new MatrixWrapper<double>(data, 80, 60);
        wrapper[2, 2] = 2.0;
Henk Holterman