繁体   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