tags:

views:

380

answers:

7

I know how to do this via streamreader and read to the end of line, but was curious if there was a fancier way of going it (for the sake of learing).

filename: blah.csv

File layout is simple:

"Some234234        ", 234
"blahblha234234    ", 2322

I want to load this into a dictionary (the second part should be a int, but I will parse later in case of errors).

Can you do this via linq somehow?

+3  A: 

You should use the TextFieldParser class in Microsoft.VisualBasic.dll. (There's nothing wrong with using it in C#.

Remember that CSV is a much more complicated file format than you think; both quotes and newlines can be escaped.

SLaks
+3  A: 

Untested, but:

static IEnumerable<string> ReadLines(string path) {
    using (var file = File.OpenText(path)) {
        string line;
        while ((line = file.ReadLine()) != null) {
            yield return line;
        }
    }
}

var data = (from line in ReadLines(path)
            select line.Split(','))
           .ToDictionary(
              arr => arr[0].Trim('"', ' '),
              arr => int.Parse(arr[1].Trim()));
Marc Gravell
This will not handle escaped CSV files. Even if the CSV files aren't escaped right now, they might be in the future.
SLaks
+1 yours has yield and trims :)
Pharabus
+1  A: 
foreach (string s in File.ReadAllLines(filename)) {
 var vals = s.Split(',')
 dictionary[vals[0]] = vals[1];
}

No LINQ but this is simple really. Doesn't handle embedded ',''s in the first value though.

Ron Warholic
This will not handle escaped CSV files. Even if the CSV files aren't escaped right now, they might be in the future.
SLaks
He obviously doesn't care about things like this as he put it "for the sake of learing." CSV isn't even a standardized format, his CSV might not allow escaping.
Ron Warholic
+2  A: 
 string[] file = File.ReadAllLines(@"C:\temp\dictionary.txt");

      Dictionary<string, string> b = (from p in file
                                     let x = p.Split(',')
                                     select x).ToDictionary(a => a[0], a => a[1]);
Pharabus
This will not handle escaped CSV files. Even if the CSV files aren't escaped right now, they might be in the future.
SLaks
+1  A: 

You could use File.ReadAllLines(), Select() and ToDictionary() to do this:

var d = File.ReadAllLines(file).Select( l => {
  var split = l.Split(',');
  return new { Key = split[0], Value = split[1] };
} ).ToDictionary( p => p.Key, p => p.Value );

But there are obvious problems here with respect to error handling and robustness, and as you add those, it gets worse and worse. I don't feel there's a particular good reason prefer LINQ or its extension methods here, as it isn't buying you much. The straightforward ways, posted already, are much cleaner.

EDIT: Sid's answer, for example, contains essentially the same code, but written in a much, much cleaner form by avoiding all this "fancy" junk.

Josh Petrie
+2  A: 

CSV can be a lot more complicated than it appears at first. Here is an excellent library for reading CSV files.

http://www.codeproject.com/KB/database/CsvReader.aspx

Sam
I agree with this and with SLaks's reply. The most effective way to solve any problem is to use a solution that already exists. CSV seems to be one of those features that's just simple enough for people to re-invent on a whim, but still complex enough for most of them to make a mess out of.
Aaronaught
A: 

This might be overkill in your simple scenario, but for CSV to strongly typed collection conversion, I usually use FileHelpers.

It's a great tool to have in the tool box.

Martin R-L