Suppose I have an array of strings like :
myArray["hello", "my", "name", "is", "marco"]
to access to this variable, I have to put an integer as index. So if I wanto to extract the third element I just do :
myArray[2]
Now, I'd like to use label instead of integer.
So for example somethings like :
myArray["canada"]="hello";
myArray["america"]="my";
myArray["brazil"]="name";
myArray["gosaldo"]="is";
myArray["italy"]="marco";
How can I do this on C#? Is it possible? Thanks
That's called an associative array, and C# doesn't support them directly. However, you can achieve exactly the same the effect with a Dictionary<TKey, TValue>. You can add values with the Add method (which will throw an exception if you try to add an already existing key), or with the indexer directly, as below (this will overwrite the existing value if you use the same key twice).
Dictionary<string, string> dict = new Dictionary<string, string>();
dict["canada"] = "hello";
dict["america"] = "my";
dict["brazil"] = "name";
dict["gosaldo"] = "is";
dict["italy"] = "marco";
C# has a Dictionary class (and interface) to deal with this sort of storage. For example:
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("canada", "hello");
dict.Add("america", "my");
dict.Add("brazil", "name");
dict.Add("gosaldo", "is");
Here are the docs: http://msdn.microsoft.com/en-us/library/xfhwa508.aspx
With a Dictionary you will be able to set the "key" for each item as a string, and and give them string "values". For example:
Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("canada", "hello");
You're looking for an associative array and I think this question is what you're looking for.
Related
I want to build a dictionary composed by 2 keys and 1 value. Is that possible?
Dictionary<(key1, key2), Type> dict = new Dictionary<(key1, key2), Type>();
Then I want to find in my dictionary by this 2 keys and get the Type. I tried that key1 and key2 were inside an object like this
Dictionary<Object, Type> dict = new Dictionary<Object, Type>();
Then I added into my dictionary an new instance object with the attributes like this
//myObject has many attributes that are empty and I just fill this 2 ones to build my dict
Object myObject = new Object();
myObject.Key1 = "A";
myObject.Key2 = "B";
dict.Add(myObject, (Type)objType);
But, the object that I want to find is loaded with data from DB and has probably many attributes filled.
The thing is when I use the TryGetValue returns nothing, so I think it's because is looking by the same reference which is not the same.
Well the question, how can I build my dictionary with 2 keys (STRING, STRING) and 1 return value (TYPE) in a easy way.
Thanks
Not sure what you mean by 2 keys. If you want a key containing two values, use Tuple, e.g.
Dictionary<Tuple<int, int>, string>
Another option is to use dictionary of dictionary, e.g.
Dictionary<int, Dictionary<int, string>>
I would use the following:
Dictionary<Tuple<string, string>, Type>
From the msdn page here:
http://msdn.microsoft.com/en-us/library/dd270346.aspx
I believe that the Equals method has been overridden for Tuple, so you should get key matching on the contents of the Tuple rather than the object reference.
Adding to dict would be:
dict.Add(new Tuple<string,string>(myObject.Key1, myObject.Key2), (Type)objType);
I have a table contains the columns Title and Info.
I would like to create an array it's index will be the Title, and actual value of the array in that index is the Info in the same row.
So if I have 3 Rows like that:
Title Info
ABC Hi
DEF Sup
GHI Hello
I would like to ask for StringArray["ABC"], and this will return "Hi".
How can I do that?
Thanks Guy
You want a Dictionary<String, String>, not a string array.
var myStrings = new Dictionary<String, String>();
myStrings.Add("ABC", "Hi");
myStrings.Add("DEF", "Sup");
myStrings.Add("GHI", "Hello");
Console.WriteLine(myStrings["ABC"]);
Arrays can only be indexed with an integer. You would have to use Dictionary<string, string>, or some other type that implements IDictionary<string, string>, or you could implement your own type with a string indexer.
Please refer to Dictionary for that
You can do in this way
Dictionary<string, string> Book = new Dictionary<string, string>();
Book.Add("ABC","Hi");
Book.Add("DEF","Sup");
Book.Add("GHI","Hello");
so on and so forth.
So then when you say
Book["ABC"] it will return Hi
You should use dictionary to implement it.
var table = new Dictionary<string,string>(
{"ABC", "Hi"},
{"DEF", "Sup"},
{"GHI", "Hello"}
);
now you can use it
var info = table["ABC"];
you should be careful an exception will be thrown if you use unexisted key
you can use TryGetValue to avoid this exception
string info;
if(!table.TryGetValue("ABC", out info))
{
info = "default value if required";
}
I have tried reading the other posts on this subject and can't quite figure this out.
I have a list in C# that I want to put in a dictionary with all of the same keys. The list is this
string[] IN ={"Against","Like","Upon","Through","Of","With","Upon","On","Into","From","by","that","In","About","For"
,"Along","Before","Beneath","At","Across","beside","After","Though","Among","Toward","If"};
I want to create and populate a dictionary with the key being "IN" (the name of the array) and then having each string for the array in the dictionary.
This is what I wrote to create the dictionary (which I am not sure is correct):
Dictionary<string, List<string>> wordDictionary = new Dictionary<string, List<string>> ()
But I am not sure how to populate the dictionary.
Any help would be greatly appreciated as this is the first time I have tried to use a dictionary and I am new to C#
An array is string[], not List<string>, so just do this:
Dictionary<string, string[]> wordDictionary = new Dictionary<string, string[]>();
Now you can add your array as usual.
wordDictionary.Add("IN", IN);
Or:
wordDictionary.Add("IN", new string[] {"Against","Like","Upon","Through","Of","With","Upon","On","Into","From","by","that","In","About","For","Along","Before","Beneath","At","Across","beside","After","Though","Among","Toward","If"});
Dictionary.Add("IN", new List<string>(IN));
...if you want to keep the current signature for your dictionary.
If you change it to Dictionary<string, string[]> then you can just:
Dictionary.Add("IN",IN);
You currently have a string array, not a list - so it should be:
Dictionary<string, string[]> wordDictionary = new Dictionary<string,string[]> ()
Then you can just add items like:
wordDictionary.Add("IN" , IN);
Do you really need to convert your array into a string? You could very well use string[] instead of List in your dictionary:
var wordDictionary = new Dictionary<string, string[]>();
wordDictionary.Add("IN", IN);
But if you really want to convert your string array to List:
var wordDictionary = new Dictionary<string, List<string>>();
wordDictionary.Add("IN", IN.ToList());
Another way to add the array (it's not a list) to the dictionary is to use collection initializer:
var wordDictionary = new Dictionary<string, string[]> { "IN", IN };
This is exactly the same as creating the dictionary in a normal way and then calling Add("IN", IN).
This question already has answers here:
C# dictionary - one key, many values
(15 answers)
Closed 8 years ago.
I need a Dictionary like object that can store multiple entries with the same key. Is this avaliable as a standard collection, or do I need to roll my own?
To clarify, I want to be able to do something like this:
var dict = new Dictionary<int, String>();
dict.Add(1, "first");
dict.Add(1, "second");
foreach(string x in dict[1])
{
Console.WriteLine(x);
}
Output:
first
second
In .NET 3.5 you can use a Lookup instead of a Dictionary.
var items = new List<KeyValuePair<int, String>>();
items.Add(new KeyValuePair<int, String>(1, "first"));
items.Add(new KeyValuePair<int, String>(1, "second"));
var lookup = items.ToLookup(kvp => kvp.Key, kvp => kvp.Value);
foreach (string x in lookup[1])
{
Console.WriteLine(x);
}
The Lookup class is immutable. If you want a mutable version you can use EditableLookup from MiscUtil.
I would recommend doing something like this:
var dict = new Dictionary<int, HashSet<string>>();
dict.Add(1, new HashSet<string>() { "first", "second" });
Dictionary<T,K> does not support such behavior and there's no collection in the base class library providing such behavior. The easiest way is to construct a composite data structure like this:
var data = new Dictionary<int, List<string>>();
As the second parameter you should use a collection which provides the qualities you are looking for, i.e. stable order ⇒ List<T>, fast access HashSet<T>, etc.
You definitely want to use NameValueCollection:
using System.Collections.Specialized;
NameValueCollection nvc = new NameValueCollection();
nvc.Add("pets", "Dog");
nvc.Add("pets", "Rabbit");
Console.WriteLine(nvc["pets"]);
//returns Dog,Rabbit
What you're looking for isn't actually a Dictionary in the traditional sense (see Associative Array).
There's no class, as far as I'm aware, that offers this in the framework (System.Linq.Lookup doesn't expose a constructor), but you could create a class yourself that implements ILookup<TKey, TElement>
You could perhaps use a Dictionary on your primary key, in which each element is a List or other collection on your secondary key. To add an item to your data structure, see if the primary key exists. If not, create a new single-item list with your Value and store it in the dictionary. If the primary key does exist, add your Value to the list that's in the dictionary.
I would like to use Dictionary as TKey in another Dictionary. Something similar to python. I tried this but it gives me errors.
Dictionary<Dictionary<string, string>, int> dict = new Dictionary<Dictionary<string, string>, int>();
Dictionary<string, string> dict2 = new Dictionary<string, string>();
dict2["abc"] = "def";
dict[dict["abc"] = 20;
What error is it giving you? Is it complaining about your missing bracket on line 4?
Line 4 looks like it should be:
dict[dict["abc"]] = 20;
However, you probably mean this, since "abc" is not a key of dict:
dict[dict2["abc"]] = 20;
But dict2["abc"] is a string, when the key of dict is supposed to be a Dictionary<string, string>.
But let's re-examine your original goal at this point before going to far down this path. You shouldn't be using mutable types as dictionary keys in the first place.
This may be the code you're looking for:
Dictionary<string, int> dict = new Dictionary<string, int>();
Dictionary<string, string> dict2 = new Dictionary<string, string>();
dict2["abc"] = "def";
dict[dict2["abc"]] = 20;
But it's hard to tell for sure.
Just to throw this in there, I often find that dealing with complicated dictionaries like you describe it's far better to use real names with them rather than trying to let the reader of the code sort it out.
You can do this one of two ways depending on personal preference. Either with a using statement to create a complier alias. Note you have to use the fully qualified type name since this is a compiler alias.
using ComplexKey = System.Collections.Generic.Dictionary<String, String>;
using ComplexType = System.Collections.Generic.Dictionary<
System.Collections.Generic.Dictionary<String, String>,
String
>;
Or you can go the full blown type way and actually create a class that inherits from Dictionary.
class ComplexKey : Dictionary<String, String> { ... }
class ComplexType : Dictionary<ComplexKey, String> { ... }
Doing this will make it far easier for both you and the reader of your code to figure out what you're doing. My general rule of thumb is if I'm creating a generic of a generic it's time to look at building some first class citizens to represent my logic rather.
It's because the "dict["abc"] is not dictionary, but "string".
The correct, what you asked is:
Dictionary<Dictionary<string, string>, int> dict = new Dictionary<Dictionary<string, string>, int>();
Dictionary<string, string> dict2 = new Dictionary<string, string>();
dict2["abc"] = "def";
dict[dict2] = 20;
But i'm not sure, this is what you realy want/need.