I'm planning to create a class representing a html table, problem is that it must be able to contain 3+ dimensions, one dimension will be the width of course, the rest will be along the length like this:
foo1:bar1
foo1:bar2
foo2:bar1
foo2:bar2
etc.
Now I'm contemplating how to represent this in my class, my idea is to use a multi-level dictionary, i.e. one that can be indexed like this: myDict[fooKey][barKey][...], is that a good idea? Is it possible? How?
Can I let the user of the class give it any Dictionary along with an int depth and then cast to dictionary when using the class internally?
edit: Seems like I was a bit unclear, there is a practical depth limit obviously, but I'd prefer to code it for any depth, the depth should be given by the user of the class.
you can use a Dictionary with type of Key Dictionary...
so you can say:
Dictionary<string, Dictionary < string, string>> x;
and use it as mentioned of you..
x["asdf"]["asdf"] = "asdf";
Related
I am working with C# for a Hexagon shaped grid with bound checks and wrapping etc. The map in the library is a dictionary Dictionary<TileCoord,int> tileIndexByPosition. I also have the required function to obtain CornerCoord for each tile.
I would like to create a dictionary Dictionary<CornerCoord,int> cornerIndexByPosition whose values depend on tileIndexByPosition. Whenever tileIndexByPosition changes its elements creating a new dictionary for corners seems quite inefficient.
The idea I have is to use the Lazy evaluation of LINQ to strongly couple the two dictionary. Would like any advice on how to approach this problem.
EDIT: I use these dictionary to check if a TileCoord or CornerCoord is part of the map by using the ContainsKey.
I would use a KeyValuePair like this
KeyValuePair<Dictionary<TileCoord,int>,Dictionary<CornerCoord,int>> kvp;
If you change the Key ( tileIndexByPosition ) you also can change the Dictonary Value of the KeyValuePair Value that depends on the KeyValuePair Key.
This is like you said you want. But I think you want something like this:
Dictonary<KeyValuePair<TileCoord,int>,KeyValuePair<CornerCoord,int>> dic;
I hope this helps.
Kind regards
I'm trying to come up with a good model for (what I would consider) a somewhat complicated class. There are two entities which are independent of each other (in that they have use, by themselves, elsewhere in the app), a User Group and an Event Type.
A User Group has a list of event types to which they are entitled. And beyond that, there is a list of strings which applies to each combination of User Group and Event which tells the app strings to replace later on (so a Dictionary where they key is a field to replace and the value is the value to replace it with).
I come from more of a SQL background, so it's easy for me to think in terms of tables and primary keys. This structure would be keyed off UserGroupID, EventTypeID, NameToReplace, but when I try to come up with a way to do it in C#, I end up with ugly (or at least I think they're ugly) structures like Dictionary<int, Dictionary<tuple<int, string>, string>> or Dictionary<int, Dictionary<int, Dictionary<string, string>>>
I could also do away with the dictionary concept and just make a list of tuples, or a list of custom classes which tie all the logical "keys" together.
My question(s) come down to, is this sort of nested collection structure common and/or a good idea? Are there best practices when modeling data like this anyone can point me to?
Thanks in advance!
So, this might be controversial, but I wanted to put this version out for discussion, to know how appropriate this approach would be.
Assuming you don't have millions of groups and event types, you could pack those into kind of Composite Key in db terms with bits shift :
public static int Combine(int value1, int value2)
{
return value1 | (value2 << 8);
}
Then Dictionary<int, string> would be work fine.
dictionary.Add(Combine(UserGroupID, EventTypeID), NameToReplace)
And to get the value :
dictionary[Combine(UserGroupID, EventTypeID)] // Or TryGetValue()
Normally, I use a dictionary like a list, but with a key of a different type. I like the ability to quickly access individual items in the dictionary without having to loop through it until I find the item with the right property (because the property I'm looking for is in the Key).
But there is another possible use of a dictionary. I could just use the Key to store property A and the Value to store property B without ever using the dictionary's special functionality. For example, I could store a list of persons just by storing the forename in the key and the family name in the value (let's assume, for the sake of simplicity, that there won't ever be two people with the same forename, because I just couldn't come up with an better example). I would only use that dictionary to loop through it in a foreach loop and add items to it (no removing, sorting or accessing individual items). There would actually be no difference to using a List<KeyValuePair<string, string>> from using a Dictionary<string, string> (at least not in the example that I gave - I know that I could e. g. store multiple items wiht the same key in the list).
So, to sum it up, what should I do when I don't need to use the special functionalities a dictionary provides and just use it to store something that has exactly two properties:
use a Dictionary<,>
use a List<KeyValuePair<,>
use a List<MyType> with MyType being a custom class that contains the two properties and a constructor.
Don't use dictionaries for that.
If you don't want to create a class for this purpose, use something like List<Tuple<T1,T2>>. But keep in mind a custom class will be both more readable and more flexible.
Here's the reason: it will be much more easy to read your code if you use proper data structures. Using a dictionary will only confuse the reader, and you'll have problems the day a duplicate key shows up.
If someone reads your code and sees a Dictionary being used, he will assume you really mean to use a map-like structure. Your code should be clear and your intent should be obvious when reading it.
If you're concerned with performance you should probably store the data in a List. A Dictionary has lots of internal overhead. Both memory as well as CPU.
If you're just concerned with readability, chose the data structure that best captures your intent. If you are storing key-value pairs (for example, custom fields in a bug tracker issue) then use a Dictionary. If you are just storing items without them having some kind of logical key, use a List.
It takes little work to create a custom class to use as an item in a List. Using a Dictionary just because it gives you a Key property for each item is a misuse of that data structure. It is easy to create a custom class that also has a Key property.
Use List<MyType> where MyType includes all the values.
The problem with the dictionary approach is that it's not flexible. If you later decide to add middle names, you'll need to redesign your whole data structure, rather than just adding another field to MyType.
Half the time I need to find a value based on string, their name, and the other half I need to find a value based on an int, their user ID.
Currently I have two dictionaries to solve this dilemma - one that uses a string as a key and one that uses an int as a key. I was wondering if there is a more efficient way to do this - a way to get a value based on int or string.
public static Dictionary<int, Player> nPlayers = new Dictionary<int, Player>();
public static Dictionary<string, Player> sPlayers = new Dictionary<string, Player>();
After scanning the other questions, someone mentioned using a dictionary of dictionaries. If anyone can elaborate on this (if it's the solution I'm looking for), that'd be grand
I don't know much about a tuple, but from what I understand it requires two keys, and what I am looking for takes one or the other.
Would Dictionary<object, Player> do the trick? I have no idea.
Please help me in my narrow-minded coding experience. ;_;
As per your comment when user logged in to system you adding them to a dictionary, here you have to add to both dictionaries.
I think you can do this in another way,
public static List<Player> nPlayers = new List<Player>();
That's only you need, add players when they logged in.
If you want to search by ID, Name or whatever you can query nPlayers and find the Player.
var playerByID = nPlayers.Where(p= p.ID==givenID).FirstOrDefault();
var playerByName = nPlayers.Where(p= p.Name==givenName).FirstOrDefault();
I don't think having a Dictionary<object,Player> is a better idea than having two distinct dictionaries. It will probably take the same amount of memory (since each Player reference will still be stored twice in the unified dictionary), will probably be less clear, and might (conceivably) cause problems with hashcode collisions since your key can be several different types.
I would just keep two dictionary, PlayersByName and PlayersByID, and use them when appropriate.
Do you want to know in the future the original data type that was put in the Dictionary? If not, you have two options:
Stringly typed! - Just use a string as the key and when adding to it, call .ToString() on the integers :)
Be objective - Use an object as the key, that way you can put anything you like inside it.
Based on the 2, I'd recommend the first as you still have some kind of type restrictions in there.
If you do want to know the original data type in the future - your implementation is fine :)
Your solution (2 dictionaries) is correct one. Dictionary can only be indexed by one stable key. As result you have to keep separate dictionaries to index by different keys.
How do we name a dictionary variable?
Say in my method I have Dictionary<string, List<string>> dictionary;, where the keys of the dictionary are country names and the values are lists of province/state names. How should I rename dictionary?
I know we can create a Country class for this example. But please don't mention this alternative because I'm thinking of good naming convention here.
ProvincesByCountry
I use mostly one of these:
CountryToStatesDictionary
CountryToStatesMap
CountryToStatesMapping
ProvincesByCountry is not explicit enough, as it sounds like mapping countries to provinces one to one. When accessing ProvincesByCountry["Germany"] I'd expectedly assume one value is an object rather than a list of objects.
My personal pattern is similar:
[Plural of a noun describing the value]By[Singular of a noun describing the key]
However, if a noun describing the value is plural by its nature, then I use the postfix arrays, or lists, as in English you can't really "pluralise" a plural. I personally always stick to arrays, regardless of the actual implementation of IEnumerable or IEnumerable< T> I'm using, be that List, or Array or whatever.
In your case it turns to:
ProvinceArraysByCountry
Tells what it is with scientific precision.
I apply this rule recursively if there are dictionaries as values. The order of accessing then goes in reverse to the order of words in the name. Imagine you add planets:
ProvinceArraysByCountryByPlanet["Earth"]["Germany"][0] = "Bavaria"
ProvinceArraysByCountryByPlanet["Earth"]["Germany"][1] = "Rhineland-Palatinate"
And finally the last little stroke here. If such dictionary maps object properties and the objects themselves, then I leave out the word describing the object in the key section. Here is what I mean:
NodesByIndex[node.Index] = node; // - Do
NodesByNodeIndex[node.Index] = node; // - Don't
I use this pattern unconditionally which is good as it leaves absolutely no room for guess. Con is it generates fairly long names sometimes. But I have no idea how to have always explicit but always short names. You always have to compromise. And it's of course a matter of taste.
This pattern doesn't work (or at least you'd break your brain) when keys are also dictionaries or when you have list of dictionaries of lists of dictionaries or some other crazy exotic stuff. But I don't remember having that many levels of nesting, so I'm happy with it.
I like XtoYMap or YFromX.
Naming is always contextual. So in this specific case some name specifying the country to state mapping is appropriate.
if this was just a device for a loop within a larger context and then discarded, I normally just go with a short temp type var like...
var dict = GetCountryStateMapping();
foreach(var item in dict)
{
//Something....
}
provinces, provinceMap, provinceDictionary
All come to mind. I like provinceMap my self. If it's a member field I would add an "m_" prefix, as in "m_provinceMap".