CSV — файл содержит разные строки

#c#

Вопрос:

У меня есть csv-файл, который выглядит так:

 M;2017.12.01 17:04;1;example@example.com

T;1;K001;2

T;1;N001;1

M;2017.11.01 15:56;2;example@example.com

T;2;P001;2

T;2;P001;1
 

Моя проблема в том, что я должен прочитать этот файл в a List<> и иметь возможность перемещаться по нему с помощью индексов, но различные типы строк после длинных меня смущают.

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

Комментарии:

1. Вам нужно будет разветвить код по крайней мере на один, если для разбора строк двух разных типов

2. Что представляют собой короткие строки? Связаны ли они с предыдущей длинной строкой?

3. Да, длинные строки представляют клиента, который что-то купил, а короткие строки под ними представляют данные о купленном товаре.

Ответ №1:

Вы можете попытаться идентифицировать строку перед ее созданием.
затем вы можете создать два разных метода для инициализации вашего заказа.

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

Эти два метода будут чем-то вроде

 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])
};
 

И, наконец, два разных класса, один для заказа и один для товара, Order должны содержать список товаров.

Ответ №2:

Попробуйте что-нибудь вроде:

 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" amp;amp; lastCustomer != null)
   {
      lastCustomer.AddOrder(values);
   }
}
 

(вам нужно будет написать класс Customer, который может создавать себя из массива строк, а также имеет метод добавления новых объектов заказа в свой собственный список заказов, снова создавая их из массива)