Click here to Skip to main content
15,559,275 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:

I have a DataTable. It's first column contains a string ID code. The following columns of the table have various data that I need to iterate through and count. ID codes can occur multiple times throughout the DataTable.

I would like to use a multi-valued dictionary for three distinct integer values (e.g. X, Y and Z). Each of these integers are associated with the ID code. The code I have so far is:

public struct Coordinates
    public int x;
    public int y;
    public int z;

public class CoordinatesDictionary : Dictionary<string, Coordinates>
    public void Add(string key, int X, int Y, int Z)
        Coordinates val;
        val.x = X;
        val.y = Y;
        val.z = Z;
        this.Add(key, val);

var dict = new CoordinatesDictionary();

The DataTable would have no more than several thousand rows, most of which would be repeating ID values.

How can I change one of the specific integer values for a particular key? E.g. for Key "A", change integer Y only? I need to update key coordinate values (X, Y and Z) as I iterate through the rows of the DataTable.

Or should/could I use something different than a multi-valued dictionary.

Thanks in advance.

What I have tried:

I had a good look on via google. Just can't seem to find exactly what I'm after. Happy to try alternatives to dictionaries.
Updated 2-Jan-21 3:45am
Member 15023217 2-Jan-21 19:00pm    
I have an additional question. If I was to include a List<int> in the Coordinates class, how could I update specific list value as I iterate through the DataTable? The List<int> along with ints X, Y and Z all belong to a specific key in the multi-value dictionary.

The problem is that Coordinates is a struct - so it's a value type, and that means that what is returned by dict["A"] is not a variable - it's a copy of the value of a variable, and can't be directly altered because it's not a lvalue
You can store the result in a variable and change that:
Coordinates c = dict["A"];
c.y = 666;
but as this is a value type, that will not modify the dictionary in any way.

Probably the best way is to change your struct to a class:
static void Main(string[] args)
    CoordinatesDictionary dict = new CoordinatesDictionary();
    dict.Add("A", 1, 10, 100);
    dict.Add("B", 2, 20, 200);
    dict.Add("C", 3, 30, 300);
    dict["A"].Y = 666;
public class Coordinates
    public int X { get; set; }
    public int Y { get; set; }
    public int Z { get; set; }

public class CoordinatesDictionary : Dictionary<string, Coordinates>
    public void Add(string key, int x, int y, int y)
        this.Add(key, new Coordinates() { X = x, Y = y, Z = z });
Since your Coordinates will be stored in a Dictionary, the struct would need to be boxed anyway, and a class may well be more efficient as a result.
This may help (even if it doesn't mention Dictionaries!): Using struct and class - what's that all about?[^]
Share this answer
Member 15023217 2-Jan-21 2:28am    
Perfect! Thank you OriginalGriff.
OriginalGriff 2-Jan-21 2:38am    
You're welcome!
OriginalGriff 3-Jan-21 4:32am    
Re your List: I would suspect that the best way to do that would be to make the Dictionary hold a string Key and List of Coordinate values, rather than include the list as part of the Coordinate.
Richard MacCutchan 2-Jan-21 9:47am    
Thanks, just what I need for a little project of mine.
BillWoodruff 2-Jan-21 21:31pm    
Hi Griff, I'd consider it a gift if you would let me know if you think I am misinterpreting the OP's question in my response below. thanks, Bill
The reason to use a C# generic Dictionary is to have an efficient key-based look-up data structure (internally, it is implemented with a HashSet).

Each Key must be unique !
ID codes can occur multiple times throughout the DataTable.
This implies, to me, that you think you can have duplicate keys.

I suggest you make the first DataTable Column an auto-incrementing Int: it's easily done:
DataColumn column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.AutoIncrement = true;
column.AutoIncrementSeed = 0;
column.AutoIncrementStep = 1;
Note that the the AutoIncrement is only triggered for new rows that are added after the column is added.

then add another Column with some form of Type Code Identifier, like "A" or "B" or whatever. Use the Int as the Key in your Dictionary.

Then you can easily sort on the type-identifier, Use Linq to filter for matches, etc.
Share this answer
Member 15023217 2-Jan-21 18:57pm    
Thanks for your suggestion. As stated, the DataTable has the IDs (often multiples of the one ID) and various data associated with them. The purpose of the multi-valued dictionary is to tally the data from the DataTable for each ID. I iterate through that DataTable, tallying data for each ID per iteration. These tallies are stored in the dictionary for later reference.
BillWoodruff 2-Jan-21 21:25pm    
Hi, Do you see the concern I am expressing about the generic Dictionary's requirement for unique keys ? I am willing to post a code example, if you clarify what the relationship is between the DataSet and the "multi-valued dictionary." cheers, Bill
Member 15023217 3-Jan-21 2:45am    
Hi, happy for you to send any suggested code, Bill. I'll do my best here to clarify.

The DataTable has a whole bunch of data that contains a series of records essentially. Each record/row corresponds to a particular identifier (i.e. the ID) which is in the first column of that Data Table. Preceding columns just contains various other pieces of information (coordinates) which change over a particular timeframe.

I'm interest in tallying 'particular' coordinate values. Some ID rows occur more than once. Other ID rows only occur the once. Either way, I need to tally particular ID coordinate values for each ID value.

So my thoughts were to create a multi-valued dictionary whereby the ID is the key and the X, Y and Z values of the dictionary hold these tallies. The X, Y and Z values update (for particular coordinate values) as I iterate through the DataTable row by row.

How did I go, Bill? Thanks.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900