簡體   English   中英

如何轉置數據表以獲取 C# 中的第二個數據表?

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

我是一名新的 C# 開發人員,我現在正在努力將以下 DataTable 中的列轉換為行。 我擁有的當前 DataTable 結構是:

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

我需要將其轉換為以下表結構:

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

我嘗試使用我在 Google 中找到的以下方法來實現它,但我仍然沒有得到想要的結果:

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;
        }

您能否告訴我如何將第一個 DataTable 轉換為第二個?

使用擴展方法,您可以通過創建將答案行組合在一起的隱含行號列來 pivot 原始DataTable

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;
    }
}

您可以通過傳入新列源的列名和要放置在每列中的值來使用它:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM