bagowl
bagowl

Reputation: 21

CSV file has different rows

I have a csv file that looks like this:

M;2017.12.01 17:04;1;[email protected]

T;1;K001;2

T;1;N001;1

M;2017.11.01 15:56;2;[email protected]

T;2;P001;2

T;2;P001;1

My problem is that I have to read this file into a List<> and be able to navigate in it with indexes but the different types of rows after the long ones are confusing me.

class Order
{
    public string Type { get; set; }
    public DateTime Date { get; set; }
    public string OrderID { get; set; }
    public string Email { get; set; }
    public string ItemNumber { get; set; }
    public int Quantity { get; set; }

    public Order(string[] ordered , string[] items)
    {
        Type = ordered[0];
        Date = DateTime.Parse(ordered[1]);
        OrderID = ordered[2];
        Email = ordered[3];
        Type = items[0];
        OrderID = items[1];
        ItemNumber = items[2];
        Quantity = int.Parse(items[3]);
    }

}
class Program
{
    static List<Order> orders = new List<Order>();

    static void Main(string[] args)
    {           
        Reading();
    }

    private static void Reading()
    {
        using (System.IO.StreamReader reader = new System.IO.StreamReader("orders.csv"))
        {
            while (!reader.EndOfStream)
            {
                orders.Add(new Order(reader.ReadLine().Split(';') ,  reader.ReadLine().Split(';')));                   
            }
        }
    }
}

Upvotes: 2

Views: 73

Answers (2)

Steve Todd
Steve Todd

Reputation: 1270

Try something like:

List<Customer> customers = new List<Customer>();
Customer lastCustomer = null;

foreach(var line in File.ReadLines("orders.csv"))
{
   var values = line.Split(';');

   if (values[0]=="M")
   {
      lastCustomer = new Customer(values);
      customes.Add(lastCustomer);
   }
   else if (values[0]=="T" && lastCustomer != null)
   {
      lastCustomer.AddOrder(values);
   }
}

(you'll need to write a Customer class that can construct its self from an array of strings, plus has a method for adding new Order objects to its own list of orders, again constructing them from an array)

Upvotes: 0

Giulio Caccin
Giulio Caccin

Reputation: 3052

You can try to identify the line before creating it.
Than you can create two different methods to initialize your order.

while (!reader.EndOfStream)
{
    var values = reader.ReadLine().Split(';');
    if(DateTime.TryParse(values.Skip(1).First(), out var date)) {
        orders.Add(Order.FromOrderWithDate(values));
    }
    else
        orders.Last().Items.Add(Item.FromOrderWithEmail(values));
}

The two methods will be something like

public static Order FromRow(string[] ordered) =>  
    new Order {
    Type = ordered[0],
    Date = DateTime.Parse(ordered[1]),
    OrderID = ordered[2],
    Email = ordered[3],
    Items = new List<Item>();
};
public static Item FromRow(string[] items) =>  
    new Item {
    Type = items[0],
    OrderID = items[1],
    ItemNumber = items[2],
    Quantity = int.Parse(items[3])
};

And finally two different class, one for order and one for item, the Order should contain a list for the items.

Upvotes: 1

Related Questions