简体   繁体   中英

Is there a way to get the last non-null values of each column in a C# DataTable and display them as a single row?

I want to take the last non-null values of each column in a DataTable and create a single row with them.


Sample code:

DataTable temp; // temp is the DataTable shown on the left side in the "Current Result" section
DataTable temp2; // stores the newly create DataTable row

foreach(DataRow row in temp.Rows){
    object[] Item = new object[] {};
    foreach(DataColumn col in temp.Columns){
        if (row[col] != null || row[col] != DBNull.Value || !String.IsNullOrWhiteSpace(row[col].ToString()))
        {
            Array.Resize(ref Item, Item.Length + 1);
            Item[Item.Length - 1] = row[col];
        }
    }
    temp2.Rows.Add(Item);
}

My code currently copies all of the cells from one DataTable to another, including the cells that don't have any values stored in it.

Current Result: 在此处输入图像描述


In the photo below, I blacked out all the cells except of the last non-values of each column. I want the shown values to be stored and displayed as a single row.

Desired Result: 在此处输入图像描述

It seems to me that you're just looking to add a single row to the temp2 table, which has the last non-null value for each column. If that's the case, then you can initialize the object[] with the Columns.Count size, and we can loop through the columns using the column index, which allows us to assign a new value to an existing column when we find a non-null value for it in the current row:

DataTable temp = new DataTable();
DataTable temp2 = temp.Clone();

// A single row of data that is 'Columns.Count' long
object[] lastNonNullValues = new object[temp.Columns.Count];

foreach (DataRow row in temp.Rows)
{
    // Loop through columns using the column index rather than a foreach
    for (int i = 0; i < temp.Columns.Count; i++)
    {
        var col = temp.Columns[i];

        if (row[col] != null || row[col] != DBNull.Value ||
            !string.IsNullOrWhiteSpace(row[col].ToString()))
        {
            // Now we just assign the value at the index for this column
            lastNonNullValues[i] = row[col];
        }
    }
}

// Add our single row to the results table
temp2.Rows.Add(lastNonNullValues);

I don't know if the problem is solved. Her are my suggestion to solve the problem. I would go from the last row up to the first, because the task is to have the last value from each column and then the loop is may be erlier finish, as when you go from the top to the bottom of the table. But this I think also depends on the data in the table.

DataTable temp = yourTable; // the original table
DataTable temp2 = new DataTable();

object[] lastNonNullValues = new object[temp.Columns.Count];
// Index of the last row.
int lastRow = temp.Rows.Count - 1;

// Get from the last row to the first
for (int i = lastRow; i >= 0; i--)
{
    // Don't know if necessary but if all columns has an value -> finish.
    if (lastNonNullValues.All(x => x != null)) break;

    DataRow row = temp.Rows[i];
    for (int j = 0; j < temp.Columns.Count; j++)
    {
        // Continue if some value was written
        if (lastNonNullValues[j] != null) continue;
        // None of this condition should be true, thas why should change from || to &&
        if (row[j] != null && row[j] != DBNull.Value && !string.IsNullOrWhiteSpace(row[j].ToString()))
        {
            lastNonNullValues[j] = row[j];
        }
    }
}

temp2.Rows.Add(lastNonNullValues);

Notice:

The solution of Rufus L should also be work when change the if statement from or to and-conjunction .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM