【问题标题】:Adding multiple objects as value to a key in a dictionary将多个对象作为值添加到字典中的键
【发布时间】:2016-03-02 20:10:01
【问题描述】:

我的任务是读取 CSV 文件并将文件内容放入字典中。

问题是读入的每一行都会有一个字典中已经存在的键。我被告知将读取的每一行作为值(来自类对象)添加到与该行相关的键中,即帐户。

所以文件示例在每一行看起来是这样的,大约有 10 个帐户,但有 8,000 行:

账户1,价值1,价值2,价值3

账户1,价值1,价值2,价值3

所以我被要求做的是,当已经存在一个不同的键时,我需要将对象(读入的每一行)添加到该值中。

但是当我被要求对一个对象执行此操作时,这真的让我感到困惑。我理解字典的方式是,如果键/值对是这样的(字符串,整数):

key1, 5

key1, 10

当我将第二个值添加到不同的键时,它将如下所示: 键 1, 15

当涉及到使用像 int 这样的简单值时,我完全理解这一点。

但是如果我使用一个类作为我的值:

    public class DataRecord
    {
        public string account;
        public int open;
        public int buy;
        public int sell;
        public double settleMM;
        public string underlying;
        public string symbol;
    }

到目前为止,我的应用程序如下:

    static void Main(string[] args)
    {
        double dParseSettleMM;
        int iParseOpen;
        int iParseBuy;
        int iParseSell;
        string sUnderlyingControl = string.Empty;
        string sUnderlying = string.Empty;
        string sAccount = string.Empty;
        string sAccountControl = string.Empty;

        var path = @"C:\Users\jhochbau\documents\visual studio 2015\Projects\CsvReader\CSVReaderList\Position_2016_02_25.0415.csv";

        Dictionary<string, DataRecord> vSummaryResults = new Dictionary<string, DataRecord>();

        //Sets up control to switch between sorted lists.
        Console.WriteLine("Enter 1 to sort by Account, 2 to sort by Underlying, 3 to sort by Account and Underlying");
        string control = Console.ReadLine();

        //open reader
        StreamReader r = new StreamReader(path);
        StreamWriter vWriteFile = new StreamWriter("Positions2.csv");

        //Consume first line
        r.ReadLine();

        //While loop to populate List with record Objects
        while (!r.EndOfStream)
        {

            DataRecord records = new DataRecord();
            var line = r.ReadLine();
            var values = line.Split(',');

            //Need to add into dictionary...
            if (vSummaryResults.ContainsKey(records.account))
            {
                vSummaryResults[records.account].open += records.open;
            }
            else
            {
                vSummaryResults.Add(records.account, records);
            }
        }

    }

编辑:这是我的具体问题。有人告诉我,这段代码已经可以工作了,我想了解的是如何和为什么,并试图将其可视化以理解它。

当我将该类中的每个字段添加到字典中时,它到底发生了什么?被用作值的 DataRecord 类是否只有这些字段的多个实例?

【问题讨论】:

  • 你应该把你的流式读写器包装在 usings 中
  • 是的,自动关闭功能:)
  • 你打算合并数据结构吗?例如,一条记录可能具有 DataRecord.open 的非默认值,而另一条记录可能具有 DataRecord.symbol 的非默认值?每个输入行上如何存在三个值(或者这只是一个示例,而是 DataRecord 对象的整个图像)?
  • 每个 DataRecord 对象是读入的一行(值)。读入该行的帐户是关键。

标签: c# dictionary


【解决方案1】:

使您的字典值成为 DataRecords 的列表(或其他集合)。

Dictionary<string, List<DataRecord>> vSummaryResults = new Dictionary<string, List<DataRecord>>();

然后,您可以将在执行期间找到的任何新值添加到该列表中。

选项 1:我继续修改您的代码来执行此操作。

static void Main(string[] args)
{
    double dParseSettleMM;
    int iParseOpen;
    int iParseBuy;
    int iParseSell;
    string sUnderlyingControl = string.Empty;
    string sUnderlying = string.Empty;
    string sAccount = string.Empty;
    string sAccountControl = string.Empty;

    var path = @"C:\Users\jhochbau\documents\visual studio 2015\Projects\CsvReader\CSVReaderList\Position_2016_02_25.0415.csv";

    Dictionary<string, List<DataRecord>> vSummaryResults = new Dictionary<string, List<DataRecord>>();

    //Sets up control to switch between sorted lists.
    Console.WriteLine("Enter 1 to sort by Account, 2 to sort by Underlying, 3 to sort by Account and Underlying");
    string control = Console.ReadLine();

    //open reader
    StreamReader r = new StreamReader(path);
    StreamWriter vWriteFile = new StreamWriter("Positions2.csv");

    //Consume first line
    r.ReadLine();

    //While loop to populate List with record Objects
    while (!r.EndOfStream)
    {

        DataRecord records = new DataRecord();
        var line = r.ReadLine();
        var values = line.Split(',');

        //Need to add into dictionary...
        if (vSummaryResults.ContainsKey(records.account))
        {
            vSummaryResults[records.account].Add(record);
        }
        else
        {
            vSummaryResults.Add(records.account, new List<DataRecord>());
            vSummaryResults[records.account].Add(record);
        }
    }

}

选项 2:由于您不能使用选项 1。这将序列化每条记录并将其附加到键的值。然后,您可以将其拆分为 ',' 并反序列化它。上面的方法更好,但如果你不能使用它,那么它应该可以工作。

static void Main(string[] args)
{
    double dParseSettleMM;
    int iParseOpen;
    int iParseBuy;
    int iParseSell;
    string sUnderlyingControl = string.Empty;
    string sUnderlying = string.Empty;
    string sAccount = string.Empty;
    string sAccountControl = string.Empty;

    var path = @"C:\Users\jhochbau\documents\visual studio 2015\Projects\CsvReader\CSVReaderList\Position_2016_02_25.0415.csv";

    Dictionary<string, string> vSummaryResults = new Dictionary<string, string>();

    //Sets up control to switch between sorted lists.
    Console.WriteLine("Enter 1 to sort by Account, 2 to sort by Underlying, 3 to sort by Account and Underlying");
    string control = Console.ReadLine();

    //open reader
    StreamReader r = new StreamReader(path);
    StreamWriter vWriteFile = new StreamWriter("Positions2.csv");

    //Consume first line
    r.ReadLine();

    //While loop to populate List with record Objects
    var serializer = new JavaScriptSerializer();
    while (!r.EndOfStream)
    {

        DataRecord records = new DataRecord();
        var line = r.ReadLine();
        var values = line.Split(',');

        //Need to add into dictionary...
        if (vSummaryResults.ContainsKey(records.account))
        {
            vSummaryResults[records.account] += "," + serializer.Serialize(record);
        }
        else
        {
            vSummaryResults.Add(records.account, serializer.Serialize(record));
        }
    }

}

【讨论】:

  • 希望我可以,但有人告诉我不要那样做,否则这会容易得多!
  • 这是 .NET 中序列化程序的链接。 Newtonsoft 也是一个选择。 msdn.microsoft.com/en-us/library/…
  • 我今天早上开始工作,他们让我现在开始处理选项 1。非常感谢你发布了这个,可以在此基础上再做一些事情。
猜你喜欢
  • 1970-01-01
  • 2023-03-31
  • 2017-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多