Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

collection of key-value pairs where key depends on value

I have a class MyClass

class MyClass
{
    public string Name { get; set; } // is unique among all instances
    public SomeClass Data { get; set; }
    ...
}

of which I want to store several instances in a collection. I will often need to check if an instance with a certain name exists, and if it does, retrieve that instance. Since iterating through the whole collection is not an option (performance!), I thought of a using a collection of key-value-pairs, e.g. an IDictionary<string, MyClass>.

My program will also allow renaming instances of MyClass (it will not allow renaming if name uniqueness would be violated). But if I rename a MyClass, I will also need to delete the old entry from the dictionary and add the new one (i.e. with the new name) to keep the data consistent.

The problem is that I will have several such dictionaries (which contain subsets of all MyClass instances) all over the place, and it will be hard to keep track of them and consistently update all dictionaries after every renaming.

Is there a way to keep the key-value pairs consistent automatically? I think I heard of a data structure that allows this, which exists at least in C++ (unfortunately, I have no idea how it's called). Basically, it should be a collection where the key is not just a plain string but more like a reference to a string (to the name property in this case), but behaves as if it were a string. Does such a thing exist in C#? Do you have other ideas how to keep the collections consistent?

My only idea is to have a collection of all dictionaries on the highest level of my program and to make the renaming method update all those dictionaries after the actual renaming process. But there must be a better way!


Why this question is not a duplicate of Best way to change dictionary key :

I already know that a dictionary does not allow changing the key. I am instead asking for another data structure that is somehow compatible to key changes (without losing the performance benefit completely), and I am asking for other approaches as well. So my question is much more open to input from any direction, as long as it helps to solve the problem of keeping the data consistent.

like image 305
Kjara Avatar asked Oct 17 '22 05:10

Kjara


1 Answers

As far as I understand you, your problem is this:

  • You have multiple dictionaries, each holds a part of your data
  • All your instances should have a unique name throughout all the dictionaries
  • When a name is changed:
    • First, check this name is still unique
    • Update it in whatever dictionray it lives in

I think I would tackle this problem a bit differently.

First, add an ID field to the class that would be a Guid / running number, That field should never change from the moment the instance is created.
Next, add another dictionary that would hold only the names and IDs of the instances, it should look something like this:

[{"FirstName": "Guid1"},   
{"SecondName": "Guid2"},   
{"ThirdName": "Guid3"}]  

The rest of your dictionaries will hold the ID as their key, and not the name:

[{"Guid1": {instance1}},  
{"Guid2": {instance2}}] 

Now when you change the name of an instance, all the names exist in a single dictionary that'll tell you if it already exist. And you need to change it only in the single place, since the rest of the dictionaries rely on a constant value that'll never change.
So say you want to change the name of "FirstName", the names dictionary will look like this:

[{"OtherName": "Guid1"},   
{"SecondName": "Guid2"},   
{"ThirdName": "Guid3"}] 

And the rest of the data doesn't need to change.

like image 193
CKII Avatar answered Oct 20 '22 08:10

CKII