删除 DataTable 中不包含数值的 DataRow

Remove a DataRow in a DataTable that contains no numeric values

我希望能够删除 DataTable 中包含空值的 DataRows,这些数组不包含数字数据。

正在尝试修改下面的代码,该代码转置 DataTable 以供 Google 可视化 API 使用:

private DataTable TransposeOpiate(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;
}

例如,在用于改进的行下方显示的智能感知输出中,其中后面的值不包含任何数据(这通常是数值)而是包含空索引:

如果这些行采用上述格式,我需要能够删除这些行,我该如何修改我的代码来执行此操作?

如果所有行单元格都为空值,为什么不设置阻止添加行的条件?

if (newRow.ItemArray.Any(x => x != null))
{
    outputTable.Rows.Add(newRow);
}

如果您还需要检查列,请在返回之前执行此操作 outputTable

for (int col = outputTable.Columns.Count - 1; col >= 0; col--)
{
    bool toDelete = true;

    for (int row = 0; row < outputTable.Rows.Count; row++)
    {
        if (outputTable.Rows[row][col] != null)
        {
            toDelete = false;
        }
    }

    if (toDelete)
    {
        outputTable.Columns.RemoveAt(col);
    }
 }

你可以试试这样的东西(注释在代码中):

private void CheckColumns()
{
    //table which we want to check
    DataTable table = new DataTable();
    //add column definition - first column will be string, other two are int columns
    table.Columns.Add("string column", typeof(string));
    table.Columns.Add("int column 1", typeof(int));
    table.Columns.Add("int column 2", typeof(int));

    //add data - in this example rows "abc" and "ghi" are valid because they have at least one numeric column
    table.Rows.Add(new object[] { "abc", 1, 2 });
    table.Rows.Add(new object[] { "def", null, null });
    table.Rows.Add(new object[] { "ghi", null, 2 });
    table.Rows.Add(new object[] { "jkl", null, null });

    //filter rows in a way, using Linq, that rows are filtered where at least one column has numeric value
    var validRows = table.AsEnumerable().Where(r => r.ItemArray.Any(c => IsNumeric(c))).ToList();
}

//this is helper method that code will call for each value in each row
private bool IsNumeric(object value)
{
    int outputValue;
    return int.TryParse(value.ToString(), out outputValue);
}

如果您有十进制值,那么您应该在 IsNumeric 方法中使用 decimal.TyrParse

如果您需要确保除第一列以外的所有列都具有数值,您可以这样做(跳过每行的第一个值并检查所有其他值是否为数值)...

var validRows = table.AsEnumerable().Where(r => r.ItemArray.Skip(1).All(c => IsNumeric(c))).ToList();

一旦你有了这些 'valid' 行,你就可以将该数据写入另一个 table 或者对这些数据做任何你需要做的事情......

您可以使用 .CopyToDataTable() 方法代替 .ToList(),这样您将获得包含 'valid' 行的新 DataTable。例如:

DataTable newDataTable = table.AsEnumerable().Where(r => r.ItemArray.Skip(1).All(c => IsNumeric(c))).CopyToDataTable();