cloudviz
cloudviz

Reputation: 1001

Convert strings in DataRow to double

I am reading a csv file from the web and converting it to a DataTable. The 1st column is a string. 2nd, 3rd and 4th columns are numericals. I'd like to convert the 2nd, 3rd and 4th columns to double. I've written the method below to perform this task. However, when I do the conversion "Convert.ToDouble" and store it back to the data row it seems to keep it as a string object.

public static DataTable ConvertCSVtoDataTable(string strFilePath)
{
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(strFilePath);
    HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

    StreamReader sr = new StreamReader(resp.GetResponseStream());
    string[] headers = sr.ReadLine().Split(',');
    DataTable dt = new DataTable();
    foreach (string header in headers)
    {
        dt.Columns.Add(header);
    }
    while (!sr.EndOfStream)
    {
        string[] rows = sr.ReadLine().Split(',');
        DataRow dr = dt.NewRow();
        for (int i = 0; i < headers.Length; i++)
        {                
            switch (i)
            {
                //Convert columns 1,2, and 3 to double
                case 1:
                    dr[i] = Convert.ToDouble(rows[i]); 

                    break;
                case 2:
                    dr[i] = Convert.ToDouble(rows[i]);
                    break;
                case 3:
                    dr[i] = Convert.ToDouble(rows[i]);
                    break;
                default:
                    dr[i] = rows[i];
                    break;
            }                              
        }
        dt.Rows.Add(dr);
    }

    return dt;
}

Upvotes: 2

Views: 3099

Answers (3)

Yacoub Massad
Yacoub Massad

Reputation: 27861

You need to specify the column type when you add the column. Change the code that creates the columns to something like this (based on which columns you want to have type double):

foreach (string header in headers.Take(3))
{
    dt.Columns.Add(header, typeof(double));
}

foreach (string header in headers.Skip(3))
{
    dt.Columns.Add(header, typeof(string));
}

This code will create the first three columns with type double and the rest of the columns with type string.

Quoting from this MSDN reference:

By default, the DataType for the new column is string

If you don't specify a type, then you get a column with the default type which is string.

Upvotes: 2

Antonis Tsalapakis
Antonis Tsalapakis

Reputation: 11

Instead of:

foreach (string header in headers)
{
    dt.Columns.Add(header);
}

use

for (int i = 0; i < headers.Count(); i++ )
{
    switch (i)
    {
        case 1: case 2: case 3:
            dt.Columns.Add(headers[i], typeof(double));
            break;
        default:
            dt.Columns.Add(headers[i], typeof(string));
            break;
    }
}

Upvotes: 1

Alexander Petrov
Alexander Petrov

Reputation: 14231

Replace foreach loop to

for (int i = 0; i < headers.Length; i++)
{
    if (i >= 1 && i <= 3)
        dt.Columns.Add(headers[i], typeof(double));
    else
        dt.Columns.Add(headers[i]);
}

Upvotes: 1

Related Questions