Eliaht Brantc
Eliaht Brantc

Reputation: 33

How to vertically flip the integers in a 2D array C#

I'm trying to vertically flip a 2D array, so I'm trying to turn this:

1 2 3 4 1
5 6 7 8 2 
4 3 2 1 1
8 7 6 5 2

into

8 7 6 5 2
4 3 2 1 1
5 6 7 8 2
1 2 3 4 1

So far, I've got a nested for loop,

for (int i= 0; i<rows; i++)
            {
                for (int j = 0; j<columns; j++)
                {
                    WillSmith[i, j] = arr[i,j];
                    
                }
            }

With 'WillSmith' being the flipped array, but I keep getting the same array as I entered back.

I can't figure out what I'm doing wrong

EDIT: I've now swapped it to read arr[j,i], but now I get an error saying that I've overflowed the index. I need this to be able to work for non-square arrays, and since the array I'm testing isn't square, I can't just use newArray[i,j] = oldArray[j,i].

Upvotes: 3

Views: 2296

Answers (3)

Sebastian Mathai
Sebastian Mathai

Reputation: 1

An example of fastest way to invert a 80*260 array vertically

  const int ROW = 80;
  const int COL = 260;
  public ushort[,] FlipFrameVertical(ushort[,] frame)
  {
    // ushort size is 2 bytes
    int byteSize = 2 * COL;
    ushort[,] frame_flipped = new ushort[ROW, COL];

    for (int i = 0; i < ROW; i++)
    {

        Buffer.BlockCopy(frame, (byteSize * (ROW-1-i)), frame_flipped, 
        byteSize * i, byteSize);
    }

     return frame_flipped;
   }

Change the byte size based on your data type.

Upvotes: 0

jalex
jalex

Reputation: 1524

The fastest way to do this, and for any type of array is to use Buffer.BlockCopy() to swap rows as needed.

class Program
{
    static void Main(string[] args)
    {
        var test = new int[,] {
            {1, 2, 3, 4, 1 },
            {5, 6, 7, 8, 2 },
            {4, 3, 2, 1, 1 },
            {8, 7, 6, 5, 2 } };

        var res = ReverseRows(test);

        Console.WriteLine();
        PrintArray(test);
        Console.WriteLine();
        PrintArray(res);
    }

    public static void PrintArray<T>(T[,] array, int colWidth=9)
    {
        int n = array.GetLength(0), m = array.GetLength(1);
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                Console.Write(array[i,j].ToString().PadLeft(colWidth));
            }
            Console.WriteLine();
        }
    }

    public static T[,] ReverseRows<T>(T[,] array)
    {
        int n = array.GetLength(0), m = array.GetLength(1);
        T[,] result = array.Clone() as T[,];

        for (int i = 0; i < n/2; i++)
        {
            SwapRows(result, i, n - i - 1); 
        }
        return result;
    }

    static void SwapRows<T>(T[,] array, int row1, int row2)
    {
        if (row1 == row2) return;
        int n = array.GetLength(0), m = array.GetLength(1);
        int byteLen = Buffer.ByteLength(array) / (n * m);

        T[] buffer = new T[m];
        // copy row1 to buffer
        Buffer.BlockCopy(array, row1 * m * byteLen, buffer, 0, m * byteLen);
        // copy row2 to row1
        Buffer.BlockCopy(array, row2 * m * byteLen, array, row1 * m * byteLen, m * byteLen);
        // copy buffer to row2
        Buffer.BlockCopy(buffer, 0, array, row2 * m * byteLen, m * byteLen);
    }
}

Upvotes: 0

Fildor
Fildor

Reputation: 16084

WillSmith[rows-1-i, j] = arr[i, j];

You want to keep your column index, just reverse rows column-wise. So read from start, write from end.

Upvotes: 5

Related Questions