Dictionary Syntax ==================== We have explored several ways of storing a collection of the same type of data: - arrays: built-in syntax, unchanging size of the collection - List: generic class type, allows the size of the collection to grow Both approaches allow reference to data elements using a numerical index between square brackets, as in ``words[i]``. The index provides an order for the elements, but there is no meaning to the index beyond the sequence order. Often, we want to look up data based on a more meaningful key, as in a dictionary: given a word, you can look up the definition. C# uses the type name ``Dictionary``, but with greater generality than in nontechnical use. In a regular dictionary, you start with a word, and look up the definition. The generalization is to have some piece of data that leads you to (or *maps* to) another piece of data. The computer science jargon is that a *key* leads you to a *value*. In a normal dictionary, these are likely to both be strings, but in the C# generalization, the possible types of key and value are much more extensive. Hence the generic ``Dictionary`` type must specify a type for the key and a type for the value. We can initialize an English-Spanish dictionary ``e2sp`` with :: Dictionary e2sp = new Dictionary(); That is quite a mouthful! The C# ``var`` syntax is handy to shorten it:: var e2sp = new Dictionary(); The general generic type syntax is ``Dictionary<`` **keyType**\ ``,`` **valueType** ``>`` If you are counting the number of repetitions of words in a document, you are likely to want a ``Dictionary`` mapping each word to its number of repetitions so far:: var wordCount = new Dictionary(); If your friends all have a personal list of phone numbers, you might look them up with a dictionary with a string name for the key and a ``List`` of personal phone number strings for the value. The type could be ``Dictionary>``. This example illustrates how one generic type can be built on another. There is no restriction on the value type. There is one important technical restriction on the key type: it should be immutable. This has to do with the implementation referenced in :ref:`dictionary-efficiency`. Similar to an array or ``List``, you can assign and reference elements of a ``Dictionary``, using square bracket notation. The difference is that the reference be through a key value, not a sequential index, as in:: e2sp["one"] = "uno"; e2sp["two"] = "dos"; Here is a longer csharp sequence. Csharp displays dictionaries in its own special form, as a sequence of pairs. Again, this is special to csharp. Again, the sequence is broken up with our comments:: csharp> Dictionary e2sp = new Dictionary(); csharp> e2sp; {} csharp> e2sp["one"] = "uno"; csharp> e2sp["two"] = "dos"; csharp> e2sp["three"] = "tres"; csharp> e2sp.Count; 3 csharp> e2sp; {{ "one", "uno" }, { "two", "dos" }, { "three", "tres" }} csharp> Console.WriteLine("{0}, {1}, {2}...", e2sp["one"], e2sp["two"], e2sp["three"]); uno, dos, tres... .. index:: double: dictionary; Keys If you want to iterate through a whole ``Dictionary``, you will want the syntax below, with ``foreach`` and the property ``Keys``:: csharp> foreach (string s in e2sp.Keys) { > Console.WriteLine(s); > } one two three The documentation for ``Dictionary`` says that you cannot depend on the order of processing with ``foreach``, though the present implementation remembers the order in which keys were added. .. index:: double: dictionary; ContainsKey It is often useful to know if a key is already in a ``Dictionary``: Note the method ``ContainsKey``:: csharp> e2sp.ContainsKey("seven"); false csharp> e2sp.ContainsKey("three"); true The method Remove takes a key as parameter. Like a ``List`` and other collections, a ``Dictionary`` has a ``Clear`` method:: csharp> e2sp.Count; 3 csharp> e2sp.Remove("two"); true csharp> e2sp.Count; 2 csharp> e2sp.Clear(); csharp> e2sp.Count; 0