JP Hochbaum
JP Hochbaum

Reputation: 647

Adding multiple objects as value to a key in a dictionary

I have been tasked with reading from a CSV file and putting the contents of the file into a dictionary.

The issue is that each line being read in will have a key that already exists in the dictionary. I have been told to add each line read in as value (from a class object), into they key pertaining to that line, which is the account.

So the file sample looks like this on each line, there are about 10 accounts, but 8,000 lines:

Account1, value1, value2, value3

Account1, value1, value2, value3

So what I am being asked to do is when there is a distinct key that already exist I need to add in the object (each line read in) into that value.

But this really confuses me when I am being asked to do this with an object. The way I understand dictionaries is that if the key/value pair was like this (string, int):

key1, 5

key1, 10

When I add the second value to the distinct key it would then look like this: key1, 15

I have no problem comprehending that when it comes to using simple values like an int.

But if I am using a class as my value:

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

Here is what I have for my app so far:

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

    }

Edit: Here are my specific questions. I am told that this code already works, what I am trying to understand is the how and the why and attempting to visualize this to make sense of it.

What the heck happens to each field in that class when I add it to the dictionary? Will my DataRecord class that is being used as a value, just have multiple instances of those fields?

Upvotes: 1

Views: 2953

Answers (1)

Josh
Josh

Reputation: 1744

Make your dictionary value a List (or other collection) of DataRecords.

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

You can then add to that list any new values you find during execution.

OPTION 1: I went ahead and modified your code to do this.

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

}

OPTION 2: Since you can't use option 1. This will serialize each record and append it to the key's value. You can then split it by ',' and deserialize it. The above method is better, but if you can't use it then this should work.

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

}

Upvotes: 3

Related Questions