【问题标题】:How do I convert a DataTable to a jagged array in C#?如何在 C# 中将 DataTable 转换为锯齿状数组?
【发布时间】:2014-10-16 12:47:06
【问题描述】:

我是 C# 新手,在任何地方都找不到这样的示例(尽管我见过类似的示例,但转换的是 ToString,而在我的情况下,我想要整数数组)。我有一个 DataTable 对象,

DataTable results = dbCon.ExecuteQuery("my query");

int m = results.Rows.Count; 
int n = results.Columns.Count;

我想要一个由 n 个一维数组组成的锯齿状数组(每个数组都是 DataTable 的一列(在本例中为results)。

int[][] jagged = new int[n][];

for (int i = 0; i < n; i++)
            {
                jagged[i] = new int[m];
                //var coli = results.Columns.Cast<Array>().Select(column => Convert.ToInt32(column)).ToArray();
            //jagged[i] = coli;
        }

我已经尝试了一些事情(例如我注释掉的内容),但我现在很卡住。

如果有人知道如何做到这一点,请发布一些东西!谢谢!

另外,更具体地说,我真的很想使用一个像 NumPy 提供给 Python 的函数...dataSet = np.array(dataList).astype('float')。双 for 循环不符合我的最大利益,因为我的 DataTable 很大。

【问题讨论】:

  • 每一行有不同的列数吗?还是要将列的内容变成整数数组?
  • 我有 n 列,每列有 m 行。基本上我只想要一个矩阵。但是我读了一篇关于性能的文章,并说锯齿状数组最适合矩阵乘法。 heatonresearch.com/content/…

标签: c# numpy datatable jagged-arrays


【解决方案1】:

我认为您还需要创建对象类型的数组。 DataTable DataRow 包含 object 类型的东西,因此您需要将它们存储在锯齿状数组中。

我认为这会奏效:

DataTable table = dbCon.ExecuteQuery("my query");
int rowCount = table.Rows.Count;
int colCount = table.Columns.Count;

object[][] objs = new object[colCount][];

for (int currentColumn = 0; currentColumn < colCount; currentColumn++)
{
    objs[currentColumn] = new object[rowCount];
    for (int currentRow = 0; currentRow < rowCount; currentRow++)
    {
        objs[currentColumn][currentRow] = table.Rows[currentRow][currentColumn];
    }
}

【讨论】:

  • 我不了解 Python - 但我知道当我这样做时:MessageBox.Show(objs[1][1].ToString()); 我从锯齿状数组中得到一个合法值。如果你不喜欢双 for 循环,你总是可以将它分成两个不同的方法调用——每个都有一个 for 循环。这样至少看起来更好..
  • 与其将值提取到程序中,不如在交错数组填充后尝试在代码中添加break,然后查看数组并查看值是否在其中。这样,您至少可以判断您的问题是来自显示值时还是填充值时出现的......
  • 好的,这行得通。在我给你分数并将这个问题标记为已回答之前的一个问题。真的没有办法像我在 Python 中那样做到这一点(即 dataSet = np.array(dataList).astype('float'))?我真的不喜欢我的代码中的双重 for 循环。只需阅读您的 cmets 就可以了,我想我现在很好。
  • 就像我说的,我从来没有接触过 Python ——但我很高兴我至少可以提供一些帮助!祝你好运。
【解决方案2】:

我想,你已经有了这个。试试:

results.Rows[rowIndex][columnIndex]

要将其放入锯齿状数组中,您可以使用简单的 for 循环:

for (int i = 0; i < results.Rows.Count; i++)
{
    for (int j = 0; j < results.Columns.Count; j++)
    {
        jagged[i][j] = results.Rows[i][j];
    }
}

【讨论】:

    【解决方案3】:

    您只需针对DataTable 使用LINQ 即可获得所需的内容。对于DataTable 中的每一列,您需要遍历行并选择该列。您需要在列上调用Cast()Select() 并在行上调用AsEnumerable() 才能Select()

    int[][] jagged = results.Columns.Cast<DataColumn>()
        .Select(
            col => results.AsEnumerable()
                .Select(row => row.Field<int>(col))
                .ToArray()
        ).ToArray();
    

    【讨论】:

    • 我想使用你的帖子 b/c 我要查询的表非常大,所以双 for 循环不符合我的最佳利益。但是我尝试了这个并得到了一个 InvalidCastException。问题似乎出在 row => row.Field 上。也许您错过了帖子中的某些内容,或者我误用了您的帖子。真的,我只想做一些像 NumPy 包允许你在 Python 中做的事情(即 dataSet = numpy.array(dataList).astype('float'))
    • @eTothEipiPlus1 我猜你的DataTable 中有额外的列不是ints。您可以在第一次选择之前使用.Where(...) 过滤列,因此您只会获得所需的列。
    • @eTothEipiPlus1 或者,将数组更改为object[][] 并使用row[col] 而不是row.Field&lt;int&gt;(col),您将获得所有列,无论类型如何。不确定它是否会避免双循环 - 嵌套的 Selects 将执行循环。
    猜你喜欢
    • 2015-06-28
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    • 2013-09-17
    • 2018-11-05
    • 1970-01-01
    • 2018-07-26
    相关资源
    最近更新 更多