Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In a timeseries of column values - how can i use previous available value if row value is null. c# (Datatable/Datarow)

I'm reading Datatable column values into an array but my current code skips null values.

Question -

How can I achieve the following within the code listed below -

If null value then read the previous available value in the time series.

**For example - note these are column values.... **

Input - 8,9,10,'','',5,11,3,'',2

Code output - 8,9,10,5,11,3,2

Expect_Result - 8,9,10,10,10,5,11,3,3,2

Code -

public static double[] DataTableColumn(DataTable table, string "dbColumn")
    {
        var column = new List<string>();
        foreach (
           string columnsize in
           from DataRow resultRow in table.Rows
           select resultRow[columnName].ToString().Split('|') into sizes
           from size in sizes
           where !column.Contains(size)
           select size)
        {
            column.Add(columnsize);
        }

        string[] columnarray = column.ToArray();
        double[] doublearray = Array.ConvertAll(columnarray, Double.Parse);

        return doublearray;
    }

FYI - DataTableColumn input DataTable table is from the below code

 public static DataTable DataSet()
    {
        string sql = string.Format(@"select * from dbtable);

        System.Data.DataTable table = new System.Data.DataTable();
        using (OracleConnection connection = new OracleConnection())
        {
            connection.ConnectionString = connectionString;
            connection.Open();

            OracleCommand command = connection.CreateCommand();

            command.CommandText = sql;
            OracleDataReader reader = command.ExecuteReader();


            table.TableName = "Table";
            OracleDataAdapter adapter = new OracleDataAdapter(command);
            adapter.Fill(table);
            Console.WriteLine("State: {0}", connection.State);
            Console.WriteLine("ConnectionString: {0}",
                              connection.ConnectionString);
        }         

        return table;
    }
like image 483
war10ck Avatar asked Nov 29 '25 07:11

war10ck


1 Answers

The below code produces your desired output with your supplied input.

What I have changed about your code is that when the value is empty, it recursively finds the previous value that is not empty.

static void Main(string[] args)
{
    var dt = new DataTable();
    dt.Columns.Add(new DataColumn("column1"));
    var values = new string[] { "8", "9|10", "", "", "5", "11", "3", "", "2" };
    foreach (var value in values)
        dt.Rows.Add(value);
    var result = DataTableColumn(dt, "column1");
    // result contains 8, 9, 10, 10, 10, 5, 11, 3, 3, 2
    Console.ReadKey(true);
}

public static double[] DataTableColumn(DataTable table, string columnName)
{
    var split = table.Rows.Cast<DataRow>()
        .SelectMany(r => r[columnName].ToString().Split('|'))
        .ToList();
    var replaceEmpty = split.Select((v, i) => 
           string.IsNullOrEmpty(v) ? Previous(split, i) : v)
        .ToArray();
    return Array.ConvertAll(replaceEmpty, Double.Parse);
}

public static string Previous(List<string> list, int index)
{
    if (index == 0)
        throw new IndexOutOfRangeException();

    var prev = list[index - 1];
    if (string.IsNullOrEmpty(prev))
        return Previous(list, index - 1);
    else
        return prev;
}
like image 120
Blake Thingstad Avatar answered Dec 01 '25 22:12

Blake Thingstad