1

I've been looking around a bit but haven't really found a good example with what I'm struggling right now.

I have a .txt file with a couple of columns as follows:

#   ID,YYYYMMDD, COLD,WATER,   OD,   OP,
    52,20120406,  112,   91,   20,  130,
    53,20130601,  332,   11,   33,  120,

And I'm reading these from the file into a string[] array. I'd like to split them into a list for example

List results, and [0] index will be the first index of the columns

results[0].ID

results[0].COLD

etc..

Now I've been looking around, and came up with the "\\\s+" split but I'm not sure how to go about it since each entry is under another one.

string[] lines = File.ReadAllLines(path);
List<Bus> results = new List<Bus>();

//Bus = class with all the vars in it
//such as Bus.ID, Bus.COLD, Bus.YYYYMMDD

foreach (line in lines) {
  var val = line.Split("\\s+");
  //not sure where to go from here
}

Would greatly appreciate any help!

Kind regards, Venomous.

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
Venom0us
  • 37
  • 7
  • There are gobs of good CSV parsers around which will return typed data. CSVHelper is an example – Ňɏssa Pøngjǣrdenlarp Jul 29 '16 at 18:59
  • Load them to a 2d structure. One line at a time: Take first, split it and insert it in the first row. Take second, split it and insert it in the next row. And so on. – Khalil Khalaf Jul 29 '16 at 19:00
  • Depending on what you do with the data, it might be easier to just query it with OleDb http://stackoverflow.com/questions/6813607/parsing-csv-using-oledb-using-c-sharp – Slai Jul 29 '16 at 19:32

5 Answers5

1

I suggest using Linq, something like this:

  List<Bus> results = File
    .ReadLines(@"C:\MyFile.txt") // we have no need to read All lines in one go
    .Skip(1)                     // skip file's title
    .Select(line => line.Split(','))
    .Select(items => new Bus(    //TODO: check constructor's syntax
       int.Parse(items[1]),
       int.Parse(items[3]),  
       DateTime.ParseExact(items[2], "yyyyMMdd", CultureInfo.InvariantCulture)))
    .ToList();
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
0

I would do

public class Foo
{
    public int Id {get; set;}
    public string Date {get; set;}
    public double Cold {get; set;}
    //...more
}

Then read the file

var l = new List<Foo>();
foreach (line in lines)
{
    var sp = line.Split(',');
    var foo = new Foo
    {
       Id = int.Parse(sp[0].Trim()),
       Date = sp[1].Trim(),//or pharse the date to a date time struct
       Cold = double.Parse(sp[2].Trim())
    }
    l.Add(foo);
}

//now l contains a list filled with Foo objects
bto.rdz
  • 6,636
  • 4
  • 35
  • 52
0

I would probably keep a List of properties and use reflection to populate the object, something like this :

var columnMap = new[]{"ID","YYYYMMDD","COLD","WATER","OD","OP"};
var properties = columnMap.Select(typeof(Bus).GetProperty).ToList();

var resultList = new List<Bus>();

foreach(var line in lines)
{
     var val = line.Split(',');
     var adding = new Bus();
     for(int i=0;i<val.Length;i++)
     {
         properties.ForEach(p=>p.SetValue(adding,val[i]));
     }

     resultList.Add(adding);
}

This is assuming that all of your properties are strings however

konkked
  • 3,161
  • 14
  • 19
0

Something like this perhaps...

results.Add(new Bus
    {
        ID = val[0],
        YYYYMMDD = val[1],
        COLD = val[2],
        WATER = val[3],
        OD = val[4],
        OP = val[5]
    });

Keep in mind that all of the values in the val array are still strings at this point. If the properties of Bus are typed, you will need to parse them into the correct types e.g. assume ID is typed as an int...

ID = string.IsNullOrEmpty(val[0]) ? default(int) : int.Parse(val[0]),

Also, if the column headers are actually present in the file in the first line, you'll need to skip/disregard that line and process the rest.

Kevin
  • 1,462
  • 9
  • 9
0

Given that we have the Bus class with all the variables from your textfile:

class Bus
{
    public int id;
    public DateTime date;
    public int cold;
    public int water;
    public int od;
    public int op;

    public Bus(int _id, DateTime _date, int _cold, int _water, int _od, int _op)
    {
        id = _id;
        date = _date;
        cold = _cold;
        water = _water;
        od = _od;
        op = _op;
    }
}

Then we can list them all in the results list like this:

List<Bus> results = new List<Bus>();

foreach (string line in File.ReadAllLines(path))
{
    if (line.StartsWith("#"))
        continue;

    string[] parts = line.Replace(" ", "").Split(','); // Remove all spaces and split at commas

    results.Add(new Bus(
        int.Parse(parts[0]),
        DateTime.ParseExact(parts[1], "yyyyMMdd", CultureInfo.InvariantCulture),
        int.Parse(parts[2]),
        int.Parse(parts[3]),
        int.Parse(parts[4]),
        int.Parse(parts[5])
        ));
}

And access the values as you wish:

results[0].id;
results[0].cold;
//etc.

I hope this helps.

MasterXD
  • 804
  • 1
  • 11
  • 18