0

I need to read data from a .csv file and store the header and the content in my object in the following format. A list of the below mentioned class.

public class MappingData
{
    private string ColumnName { get; set; }
    private List<string> Data { get; set; }
}

So for example say I have a table like as shown below,

| Name       | Phone       | City         |
|:-----------|------------:|:------------:|
| Yassser    | 32342342234 | Mumbai
| Sachin     | 32342342234 | Surat    
| Will       | 32342342234 | London

So for the above data my class should have 3 objects, first object will have the following details

ColumnName : 'Name' Data: ['Yasser', 'Sachin', 'Will']

so, this is what I am trying to do, Below is what I have started with. I am reading the file using stream reader and spliting each line with comma seperator.

private List<MappingData> GetData(string filename)
{
    var data = new List<MappingData>();
    string fullPath = GetFilePath(filename);
    StreamReader reader = new StreamReader(fullPath);
    while (!reader.EndOfStream)
    {
        string line = reader.ReadLine();
        if (!String.IsNullOrWhiteSpace(line))
        {
            string[] values = line.Split(',');
        }
    }
    return data;
}

can some one please help me mold this data into the required format. Thanks.

Bob.
  • 3,894
  • 4
  • 44
  • 76
Yasser Shaikh
  • 46,934
  • 46
  • 204
  • 281
  • Hm, why your objects are actually columns? Thats a rather strange approach. – athabaska Sep 25 '13 at 10:13
  • In you MappingData class you have a member called ColumnName. Where do you get the value for this member? It is present (as header, first line) in the input file? You split the line at the comma, but your example doesn't show any comma in the input file. – Steve Sep 25 '13 at 10:14
  • 1
    Its strange as you can easy fetch your csv file as a dataset. http://stackoverflow.com/questions/16606753/populating-a-dataset-from-a-csv-file – Anand Sep 25 '13 at 10:50

3 Answers3

0

There's an excellent library for processing the CSV files.

KentBoogard

It is very easy with the above third party library to read content from the CSV files. I would suggest this because you just seem to be starting and don't re invent the wheel.

Still, if you want to process the file in your own way, here's one working implementation. Enjoy

        var csvData = File.ReadAllLines("d:\\test.csv");

        var dataRows = csvData.Skip(1).ToList();
        var csvHeaderColumns = csvData.First().Split(',').ToList();

        var outputList = new List<MappingData>();

        foreach (var columnName in csvHeaderColumns)
        {
            var obj = new MappingData { columnName = columnName, data = new List<string>() };

            foreach (var rowStrings in dataRows.Select(dataRow => dataRow.Split(',').ToList()))
            {
                obj.data.Add(rowStrings[csvHeaderColumns.IndexOf(columnName)]);
            }

            outputList.Add(obj);
        }

This will populate your MappingData class.

0

Assuming the rest of your method is correct then try this:

private List<MappingData> GetData(string filename)
{
    var raw = new List<string[]>();
    var data = new List<MappingData>();
    string fullPath = GetFilePath(filename);
    using(var reader = new StreamReader(fullPath))
    {
        while (!reader.EndOfStream)
        {
            string line = reader.ReadLine();
            if (!String.IsNullOrWhiteSpace(line))
            {
                raw.Add(line.Split(','));
            }
        }
    }

    Func<int, MappingData> extract =
        n => new MappingData()
        {
            ColumnName = raw[0][n],
            Data = raw.Skip(1).Select(x => x[n]).ToList(),
        };

    data.Add(extract(0));
    data.Add(extract(1));
    data.Add(extract(2));

    return data;
}

You'd have to make you MappingData properties accessible though.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
0

You should create a small int variable (or bool if you prefer) to determine whether the first row has been completed :

And create each of the list objects you will need (mpName, mpPhone, mpCity), on the first row you set the ColumnName property and on the subsequent rows you add to the MappingData's data list.

Then you add each of the lists (mpName, mpPhone, mpCity) to the data list for the method and return this.

private List<MappingData> GetData(string filename) {
    List<MappingData> data = new List<MappingData>();

    int NumRow = 0;
    MappingData mpName = new MappingData();
    MappingData mpPhone = new MappingData();
    MappingData mpCity = new MappingData();


    string fullPath = GetFilePath(filename);
    StreamReader reader = new StreamReader(fullPath);
    while (!reader.EndOfStream) {
        string line = reader.ReadLine();
        if (!String.IsNullOrWhiteSpace(line)) {
            string[] values = line.Split(',');

            if (NumRow == 0) {
                mpName.ColumnName = values[0];
                mpPhone.ColumnName = values[1];
                mpCity.ColumnName = values[2];
                NumRow = 1;
            } else {
                mpName.Data.Add(values[0]);
                mpPhone.Data.Add(values[1]);
                mpCity.Data.Add(values[2]);
            }
        }
    }

    data.Add(mpName);
    data.Add(mpPhone);
    data.Add(mpCity);

    return data;
}

Hope this helps.

Nunners
  • 3,047
  • 13
  • 17