如何使用 .csv 文件中的数据添加到 C# 中的对象列表<>?

How can I add to a List<> of objects in C# with data from a .csv file?

我使用 productdetails.csv 文件中的信息创建了一个对象列表<>,我必须使用 salesdata.csv 中的信息更新该列表<>,我目前存储在一个数组中(5 int销售数量的数字),但我不知道该怎么做。我在 Product Class 中添加了另一个构造函数,认为也许我可以创建一个包含 'WeeklySales' 属性 的新对象列表<>...不幸的是我找不到任何其他类似问题的启示。在此先感谢您对这个主题的任何启发。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace q6._2
{
class Program
{
    static void Main(string[] args)
    {
        string fileName = GetDataDirectory() + "\data\salesdata.csv";

        string[] salesDetails = File.ReadAllLines(fileName);
        string[] salesCol = new string[2];

        for (int i = 1; i < salesDetails.Length; i++)
        {
            string currentLine = salesDetails[i];

            salesCol = currentLine.Split(',');

            string salesQuant = salesCol[1];
        }

        Console.ReadLine();
    }



    public static string GetDataDirectory()
    {
        string path = Directory.GetCurrentDirectory();

        char[] removeSequence = { 'b', 'i', 'n', '\', 'D', 'e', 'b', 'u', 'g' };
        string newPath = path.TrimEnd(removeSequence);

        return newPath;
    }



    public static List<Product> ReadProductFile()
    {
        string fileName = GetDataDirectory() + "\data\productdetails.csv";

        string[] productDetails = File.ReadAllLines(fileName);

        string[] lineDetails = new string[5];

        List<Product> productObj = new List<Product>();

        for (int i = 1; i < productDetails.Length; i++)
        {
            lineDetails = productDetails[i].Split(',');
            Product newProduct = new Product(lineDetails[0], lineDetails[1], lineDetails[2], Convert.ToDecimal(lineDetails[3]), Convert.ToInt32(lineDetails[4]));
            productObj.Add(newProduct);
        }

        return productObj;
    }
}

class Product
{
    public string ID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public decimal Price { get; set; }
    public int StockAvailable { get; set; }
    public int WeeklySales { get; set; }

    public Product(string id, string name, string description, decimal price, int stockavailable)
    {
        ID = id;
        Name = name;
        Description = description;
        Price = price;
        StockAvailable = stockavailable;
    }

    public Product(string id, string name, string description, decimal price, int stockavailable, int weeklysales)
    {
        ID = id;
        Name = name;
        Description = description;
        Price = price;
        StockAvailable = stockavailable;
        WeeklySales = weeklysales;
    }
}

}

假设您的 salesdata.csv 的每一行中都有 ProductID。从问题中不清楚 - 是否如此。顺便说一下 - 它 应该 有那个 ProductID,因为我看不出你如何找到要更新的产品。

好的,您已经阅读了来自 salesdata 的一行 - 现在您需要在您的列表中找到对应的产品。这里出现了一些问题,因为 List 本身并不是一个很好的数据结构 - 你必须遍历整个列表才能找到具体的产品。

因此最好将 List<Product> 更改为 Dictionary<string, Product> 并假设字典键为 Product.ID 并填充它。在这种情况下,您将能够在 O(1) 时间内找到您的产品并更新其 WeeklySales,如:

for (int i = 1; i < salesDetails.Length; i++)
{
    string currentLine = salesDetails[i];
    salesCol = currentLine.Split(',');

    string productID = salesCol[some_column_fromCSV];

    your_products_dictionary[productID].WeeklySales = Convert.ToInt(salesCol[1]);
}

请注意这是伪代码,在这里我不关心可能的空引用等等。

另请注意 - 通过 File.ReadAllLines 读取 csv 文件的所有内容然后将其存储在数组中可能不是一个好主意。因为文件可能非常大,您可能 运行 内存不足。相反,您可以打开此文件并使用 TextReader OpenReadLine 方法逐行读取。

这应该是答案。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace q6._2
{
    class Program
    {
        static void Main(string[] args)
        {
            // ReadProductFile() <- fills all the 
            List<Product> productContents = ReadProductFile();

            ReadSalesAndMergeWithProducts(ref productContents);

            foreach (Product p in productContents)
            {
                Console.WriteLine(p.ToString());
            }

            Console.ReadLine();
        }


        private static void ReadSalesAndMergeWithProducts(ref List<Product> productContents)
        {
            string[] salesDetails = File.ReadAllLines(GetDataDirectory() + "\data\salesdata.csv");
            int smallestNr = GetSmallestOfTwo(salesDetails.Length, productContents.Count);

            for (int i = 1; i < smallestNr; i++)
            {
                productContents.ElementAt(i).WeeklySales = Convert.ToInt32(salesDetails[i].Split(',')[1]);
            }
        }


        /// <summary>
        /// shortend GetDataDirectory
        /// </summary>
        /// <returns></returns>
        public static string GetDataDirectory()
        {
            return System.IO.Directory.GetCurrentDirectory().Replace("bin\Debug", "");
        }


        /// <summary>
        /// ReadProductFile
        /// </summary>
        /// <returns>List<</returns>
        public static List<Product> ReadProductFile()
        {            
            // remove the filename string and directly pass it to the read all lines
            string[] productDetails = File.ReadAllLines(GetDataDirectory() + "\data\productdetails.csv");

            // no need to classify the size here since it will return from product details. (no harm though)
            string[] lineDetails;// = new string[5];

            // create a new product object
            List<Product> productObj = new List<Product>();

            // loop over the product details
            for (int i = 1; i < productDetails.Length; i++)
            {
                // split on comma char
                lineDetails = productDetails[i].Split(',');
                // create new product
                Product newProduct = new Product(lineDetails[0], lineDetails[1], lineDetails[2], Convert.ToDecimal(lineDetails[3]), Convert.ToInt32(lineDetails[4]));
                // add product to list
                productObj.Add(newProduct);
            }

            // return List<Product>
            return productObj;
        }

        /// <summary>
        /// GetSmallestOfTwo
        /// </summary>
        /// <param name="a">int</param>
        /// <param name="b">int</param>
        /// <returns>int</returns>
        public static int GetSmallestOfTwo(int a, int b)
        {
            return (a <= b) ? a : b;
        }
    }

    /// <summary>
    /// Product class
    /// </summary>
    class Product
    {
        public string ID { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
        public int StockAvailable { get; set; }
        public int WeeklySales { get; set; }

        public Product(string id, string name, string description, decimal price, int stockavailable)
        {
            ID = id;
            Name = name;
            Description = description;
            Price = price;
            StockAvailable = stockavailable;
        }

        public Product(string id, string name, string description, decimal price, int stockavailable, int weeklysales)
        {
            ID = id;
            Name = name;
            Description = description;
            Price = price;
            StockAvailable = stockavailable;
            WeeklySales = weeklysales;
        }

        public String ToString()
        {
            return "ID: " + ID + " Name: " + Name + " Description: " + Description +
                   " Price:" + Price + "StockAvailable: " + StockAvailable + " WeeklySales: " + WeeklySales;
        }
    }
}