Tag Archives: array

Transposing the rows and columns of a 2D array, jagged array and string in C#

Download extension methods

About the download

The download is a ZIP file containing the C# file, in which you can find the extension methods.

Introduction

Sometimes, when you write a program, you might need to transpose the rows and columns of a 2D array, a jagged array (an array of arrays) or a string. In this blog post, I’ll explain you how to do that.

The methods I’ll show you in this blog post are extension methods[^]. Put these in a static class (for example,TransposeRowsColumnsExtension), and then you can call them like yourArray.TransposeRowsAndColumns(); If you don’t use .NET 3.5 or later, you cannot use extension methods. Then, just remove the this keyword from the parameter list and you can call the methods like TransposeRowsColumnsExtension.TransposeRowsAndColumns(yourArray);
Note that the methods don’t change the original array! If you want to adjust the original array, use yourArray = yourArray.TransposeRowsAndColumns();

Transposing rows and columns of a 2-dimensional array

The first thing we do here is to create a new array. The height of the new array will be the width of the original array, and the width of the new array will be the height of the original array. Then, we run a loop and fill the new array with elements. And when doing this, the columns of the original array become the rows of the new array and vice versa. But it it’s a square, we can make it a lot faster (thanks to CatchExAs for the suggestion!), by cloning the array and swapping the items inside the array itself by iterating over the half of the array, from the upper-left to the bottom-right corner, excluding the items at the diagonal, and then perform the swap. When it’s a square, we start the outer loop from 1 (not from 0, because [0, 0] is on the diagonal) and the inner loop starts at 0 and runs while j (the variable of the inner loop) is less than i (the variable of the outer loop).

public static T[,] TransposeRowsAndColumns<T>(this T[,] arr)
{
    int rowCount = arr.GetLength(0);
    int columnCount = arr.GetLength(1);
    T[,] transposed = new T[columnCount, rowCount];
    if (rowCount == columnCount)
    {
        transposed = (T[,])arr.Clone();
        for (int i = 1; i < rowCount; i++)
        {
            for (int j = 0; j < i; j++)
            {
                T temp = transposed[i, j];
                transposed[i, j] = transposed[j, i];
                transposed[j, i] = temp;
            }
        }
    }
    else
    {
        for (int column = 0; column < columnCount; column++)
        {
            for (int row = 0; row < rowCount; row++)
            {
                transposed[column, row] = arr[row, column];
            }
        }
    }
    return transposed;
}

Transposing rows and columns of a jagged array

It’s basically the same story for a jagged array (an array of arrays). But here, we cannot immediately specify the size of the arrays inside the new jagged array. So, first, we fill the new jagged array with N arrays that consist of M items. Here, N is equal to the count of columns of the original jagged array (and those columns become rows in our new jagged array), and M is equal to the count of rows in the original jagged array. For this, we don’t need an extra loop, we can just create the inner arrays in our first loop. Note: if the inner arrays of the original array don’t have an equal count of items, this method might not work properly or throw an exception.

public static T[][] TransposeRowsAndColumns<t>(this T[][] arr)
{
    int rowCount = arr.Length;
    int columnCount = arr[0].Length;
    T[][] transposed = new T[columnCount][];
    if (rowCount == columnCount)
    {
        transposed = (T[][])arr.Clone();
        for (int i = 1; i &lt; rowCount; i++)
        {
            for (int j = 0; j &lt; i; j++)
            {
                T temp = transposed[i][j];
                transposed[i][j] = transposed[j][i];
                transposed[j][i] = temp;
            }
        }
    }
    else
    {
        for (int column = 0; column &lt; columnCount; column++)
        {
            transposed[column] = new T[rowCount];
            for (int row = 0; row &lt; rowCount; row++)
            {
                transposed[column][row] = arr[row][column];
            }
        }
    }
    return transposed;
}

Transposing rows and columns of a string

Here, we have three arguments instead of one: the string, the row delimiter and the column delimiter. First, we split the string by the row delimiter (this returns an array of rows), and then we split each row by the column delimiter, to get a jagged array. After doing that, we call the TransposeRowsAndColumns method and pass the jagged array as argument. And finally, we convert the transposed jagged array back to a string.

public static string TransposeRowsAndColumns(this string str, string rowDelimiter, string columnDelimiter)
{
    string[] rows = str.Split(new string[] { rowDelimiter }, StringSplitOptions.None);
    string[][] arr = new string[rows.Length][];
    for (int i = 0; i &lt; rows.Length; i++)
    {
        arr[i] = rows[i].Split(new string[] { columnDelimiter }, StringSplitOptions.None);
    }
    string[][] transposed = TransposeRowsAndColumns(arr);
    string[] transposedRows = new string[transposed.Length];
    for (int i = 0; i &lt; transposed.Length; i++)
    {
        transposedRows[i] = String.Join(columnDelimiter, transposed[i]);
    }
    return String.Join(rowDelimiter, transposedRows);
}

Examples of usage

These examples of usage are made for .NET 3.5 and later, because these methods are extension methods. If you use a version before .NET 3.5, use YourClass.TransposeRowsAndColumns(arr) instead of arr.TransposeRowsAndColumns()

Two-dimensional array

// Example 1:
int[,] twoDimensional = { 
                            { 1, 2, 3, 4 },
                            { 1, 2, 3, 4 },
                            { 1, 2, 3, 4 }
                        };
twoDimensional = twoDimensional.TransposeRowsAndColumns();
/* Result
{
{ 1, 1, 1 },
{ 2, 2, 2 },
{ 3, 3, 3 },
{ 4, 4, 4 }
}
*/
// Example 2:
int[,] twoDimensional1 = { 
                            { 1, 2, 3, 4 },
                            { 5, 6, 7, 8 },
                            { 9, 10, 11, 12 },
                            { 13, 14, 15, 16 }
                        };
twoDimensional1 = twoDimensional1.TransposeRowsAndColumns();
/* Result:
{
  { 1, 5, 9, 13 },
  { 2, 6, 10, 14 },
  { 3, 7, 11, 15 },
  { 4, 8, 12, 16 }
}
*/

Jagged array

int[][] jagged = {
                     new int[] { 1, 2, 3, 4 },
                     new int[] { 1, 2, 3, 4 },
                     new int[] { 1, 2, 3, 4 }
                 };
jagged = jagged.TransposeRowsAndColumns();
// Result: same as for 2D array, but as a jagged array

String

// Example 1:
string str = "1 2 3 4;1 2 3 4;1 2 3 4";
str = str.TransposeRowsAndColumns(";", " ");
// Result: "1 1 1;2 2 2;3 3 3;4 4 4"
// Example 2:
string str1 =
@"1 2 3 4
1 2 3 4
1 2 3 4";
str1 = str1.TransposeRowsAndColumns(Environment.NewLine, " ");
/* Result:
@"1 1 1
2 2 2
3 3 3
4 4 4"
*/
// Example 3:
string str2 = 
@"1,2,3,4
5,6,7,8
9,10,11,12
13,14,15,16";
str2 = str2.TransposeRowsAndColumns(Environment.Newline, " ");
/* Result:
@"1,5,9,13
2,6,10,14
3,7,11,15
4,8,12,16"
*/