Venom0us
Venom0us

Reputation: 37

What is the easiest way to split columns from a txt file

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.

Upvotes: 1

Views: 777

Answers (5)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186793

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();

Upvotes: 1

MasterXD
MasterXD

Reputation: 804

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.

Upvotes: 0

Kevin
Kevin

Reputation: 1472

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.

Upvotes: 0

konkked
konkked

Reputation: 3231

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

Upvotes: 0

bto.rdz
bto.rdz

Reputation: 6720

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

Upvotes: 0

Related Questions