Return 数据表中存在的值的行和列索引

Return line and column Index of a value that exists in dataTable

this link 中提供的解决方案非常有用:

DataColumn[] columns = tbl.Columns.Cast<DataColumn>().ToArray();
bool anyFieldContainsPepsi = tbl.AsEnumerable()
    .Any(row => columns.Any(col => row[col].ToString() == "PEPSI"));

此时我的代码:

    bool find = csvDataOnlyHeader.Rows.Cast<DataRow>().Any(r => r.ItemArray.Any(c => c.ToString().Contains("SN:")));

    DataColumn[] columns = csvDataOnlyHeader.Columns.Cast<DataColumn>().ToArray();
    bool anyFieldContains = csvDataOnlyHeader.AsEnumerable()
        .Any(row => columns.Any(col => row[col].ToString() == "SN:"));

我需要什么:

  1. 在整个 DataTable 中搜索特定字符串(不关心列名或位置)。
  2. Return 包含此字符串的位置的索引(或多个索引)。 (即第 2 行第 4 列)

Select 有一个变体,可以让您捕获索引。

var matchingIndexes = csvDataOnlyHeader.Rows.Cast<DataRow>()
    .Select((r, index) => new 
        {
            isMatch = r.ItemArray.Any(c => c.ToString().Contains("SN:")),
            index
        })
    .Where(e => e.isMatch)
    .Select(e => e.index);
var firstMatch = matchingIndexes.FirstOrDefault();

为了避免 firstMatch 具有 0(意味着第一个匹配项是数组的第零个元素)和 0(意味着没有匹配的索引)之间的歧义,你可以将结果转换为可为空的整数:

...
.Select(e => (int?)e.index)
...

或者您可以使用我的 CallMeMaybe 库来获取 Maybe<int>:

var firstMatch = matchingIndexes.FirstMaybe();

您应该能够使用 DataRowCollection 类型的 IndexOf 方法获取行索引,或者@StriplingWarrior 指出 lambda 表达式的索引参数,如果行的索引在原始枚举对你来说足够可靠。

var columns = tbl.Columns.Cast<DataColumn>().ToList();
var enumerableRowCollection = tbl.AsEnumerable();

var results = enumerableRowCollection
    .Select((row, index) =>
    {
        var column = columns.FirstOrDefault(col => row[col].ToString() == "PEPSI");

        return new
        {
            Column = column,
            ColumnIndex = column != null ? columns.IndexOf(column) : -1,
            Row = row,
            RowIndex = index
        };
    })
    .Where(x => x.Column != null)
    .ToList();

for (var i = 0; i < results.Count(); i++)
{
    var result = results[i];
    Console.WriteLine($"Result {i}");
    Console.WriteLine($"RowIndex: {result.RowIndex}");
    Console.WriteLine($"ColumnIndex: {result.ColumnIndex}");
}