简体   繁体   中英

How to transpose a datatable to get the second datatable in C#?

I am a new C# developer and I am struggling now with converting the columns in the following DataTable into rows. The current DataTable structure I have is:

Id      Value
1       Test#1
1       Test#2
2       Car#1
2       Car#2
3       Airplane#1
3       Airplane#2

I need to convert it into the following table structure:

1           2           3
Test#1      Car#1       Airplane#1
Test#2      Car#2       Airplane#2

I tried to implement it using the following method I found in Google, but I am still not getting the desired result:

private DataTable GenerateTransposedTable(DataTable inputTable)
        {
            DataTable outputTable = new DataTable();

            // Add columns by looping rows

            // Header row's first column is same as in inputTable
            outputTable.Columns.Add(inputTable.Columns[0].ColumnName.ToString());

            // Header row's second column onwards, 'inputTable's first column taken
            foreach (DataRow inRow in inputTable.Rows)
            {
                string newColName = inRow[0].ToString();
                outputTable.Columns.Add(newColName);
            }

            // Add rows by looping columns      
            for (int rCount = 1; rCount <= inputTable.Columns.Count - 1; rCount++)
            {
                DataRow newRow = outputTable.NewRow();

                // First column is inputTable's Header row's second column
                newRow[0] = inputTable.Columns[rCount].ColumnName.ToString();
                for (int cCount = 0; cCount <= inputTable.Rows.Count - 1; cCount++)
                {
                    string colValue = inputTable.Rows[cCount][rCount].ToString();
                    newRow[cCount + 1] = colValue;
                }
                outputTable.Rows.Add(newRow);
            }

            return outputTable;
        }

Could you please tell me how I can transpose the first DataTable into the second one?

Using an extension method, you can pivot the original DataTable by creating the implied row number column that groups the answer rows together:

public static class DataTableExt {
    // Transpose a DataTable to a new DataTable
    // over field creates new column names
    // value field is value for new columns
    // Original datatable must be sorted in OverColFieldName then row number order
    public static DataTable Transpose(this DataTable dt, string OverColFieldName, string WithValueFieldName) {
        var res = new DataTable();
        if (dt.Rows.Count > 0) {
            var ColCount = dt.AsEnumerable().Select(r => r.Field<int>(OverColFieldName)).Distinct().Count();
            var rowCount = dt.Rows.Count / ColCount;
            var rowNumbers = Enumerable.Range(0, rowCount*ColCount).Select(rn => rn % rowCount +1);

            var rowGroups = dt.AsEnumerable()
                              .Zip(rowNumbers, (r, rn) => new { Row = r, RowNum = rn }) // associate an answer Row Number with each row
                              .GroupBy(rrn => rrn.RowNum, rrn => new { Over = rrn.Row[OverColFieldName].ToString(), With = rrn.Row[WithValueFieldName] }); // group the columns for each answer row together

            var valueDataType = dt.Columns[WithValueFieldName].DataType;
            var colNames = rowGroups.SelectMany(rg => rg.Select(r => r.Over)).Distinct().OrderBy(n => n);
            foreach (var n in colNames)
                res.Columns.Add(n, valueDataType);

            foreach (var rowGroup in rowGroups) {
                var newr = res.NewRow();

                foreach (var r in rowGroup)
                    newr[r.Over] = r.With;
                res.Rows.Add(newr);
            }
        }
        return res;
    }
}

And you can use it by passing in the Column Names for the source of the new columns and the values to be placed in each column:

var ans = dt.Transpose("Id", "Value");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM