Search code examples
c#linqfor-loopdatarowdatacolumn

Get column name by value of field in datarow


My question is actually more about optimizing something I already have working. I'm having a hard time believing there isn't a better way to do this with a LINQ query or lambda expression, so I thought I'd try here.

Each of my datatable rows has an item number and 43 quantity columns, that each correspond with a specific day. What I'm trying to do is take each row, and find the first quantity column that is greater than 0 and return that column name. My solution does work, but I'd really like to make it more efficient:

foreach (DataRow r in dt.Rows) 
{
    for (int i = 3; i <= dt.Columns.Count - 1; i++) 
    {
        tempCol = dt.Columns(i).ColumnName.ToString();
        rowValue = Convert.ToInt32(r(tempCol));
        if (rowValue > 0) 
        {
            tempCol = tempCol.Replace("Apat", "");
            break;
        }
    }

    var FirstAvailableDate = WorkDate.AddDays((dec)tempCol).ToShortDateString;
    //use data in someway
}

Thanks for any suggestions ahead of time!!


Solution

  • the current code, each row * each column

    1. get name of column
    2. store it in variable
    3. in match case perform String.Replace

    my suggestion:

    var allCols = dt.Columns
                    .Cast<DataColumn>()
                    .Select(col => col.ColumnName.Replace("Apat", ""))
                    .ToArray();
    
    foreach (DataRow r in dt.Rows)
    {
        var firstCol =
        r.ItemArray.Select((cell, position) => Tuple.Create(Convert.ToInt32(cell), position))
                   .FirstOrDefault(tuple => tuple.Item1 > 0);
    
        if(firstCol == null) continue;        
    
        var colName = allCols[firstCol.Item2];
    
        var FirstAvailableDate = WorkDate.AddDays((dec)colName).ToShortDateString;
        //use data in someway
    }