Skip to content
Lesson 8 of 12

Step 1 of 6 · Reading · ~3 min

Learn

Collections and LINQ

Lists and Dictionaries

By the end of this lesson you can keep a growing sequence of values in a List<T>, look values up by key in a Dictionary<K, V>, and turn a line of text into pieces you can store in either.

Arrays are fixed-size: an int[5] holds five ints forever. Real programs rarely know their sizes up front, so the collection you will use daily is List<T>, a dynamic array that grows as you add. Its partner Dictionary<K, V> is a hash map: fast lookup by key. Both live in System.Collections.Generic.

List<T>

using System.Collections.Generic;

List<string> queue = new List<string> { "ann", "raj", "li" };   // collection initializer
queue.Add("bo");                       // grows automatically
Console.WriteLine(queue.Count);        // 4  (Count, not Length)
Console.WriteLine(queue[1]);           // raj (zero-indexed)
queue.RemoveAt(0);                     // remove by position: raj, li, bo
bool waiting = queue.Contains("li");   // true
queue.Sort();                          // bo, li, raj

The <string> is a generic type parameter: this list holds strings and nothing else, checked at compile time. Asking for queue[10] when there are 3 items throws ArgumentOutOfRangeException; check Count first.

Dictionary<K, V>

A dictionary stores key/value pairs. Each key appears once, and lookup by key does not scan the whole thing:

Dictionary<string, int> stock = new Dictionary<string, int>();
stock["pens"] = 12;                    // the indexer adds a new key...
stock["pens"] = 15;                    // ...or overwrites an existing one
stock["tape"] = 4;

int n;
if (stock.TryGetValue("glue", out n)) {   // safe lookup: false when the key is missing
    Console.WriteLine(n);
}
Console.WriteLine(stock.ContainsKey("tape"));   // True
Console.WriteLine(stock["glue"]);               // crash: KeyNotFoundException

Reading a missing key with the indexer throws. ContainsKey and TryGetValue are the safe ways to ask first. That matters when you update a value that may not exist yet. Adding to a running total per category looks like this:

if (sales.ContainsKey(city)) {
    sales[city] += amount;        // key exists: add to its value
} else {
    sales[city] = amount;         // first time we see this city
}

sales[city] += amount on a key that does not exist yet would throw before it could add anything.

To go through a dictionary, use foreach (KeyValuePair<string, int> kv in stock) and read kv.Key and kv.Value. The order is not something to rely on. When output must be in a known order, copy the keys into a list and sort that:

List<string> items = new List<string>(stock.Keys);
items.Sort();                          // alphabetical for lowercase letters
foreach (string item in items) {
    Console.WriteLine(item + ": " + stock[item]);
}

Splitting a line of text

Split chops a string into an array of pieces. With a single space as the separator, every extra space produces an empty piece:

string[] a = "one  two".Split(' ');    // 3 pieces: "one", "", "two"
string[] b = "one  two".Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);   // 2 pieces

Use RemoveEmptyEntries whenever the input might have doubled, leading or trailing spaces. To read numbers, parse each piece with int.Parse and Add it to a List<int> inside a foreach.

Common mistakes

  • Indexing a missing key. counts[word] += 1 throws on the first sighting of a word. Check with ContainsKey first.
  • Length versus Count. Arrays have Length; lists and dictionaries have Count.
  • Relying on dictionary order. The enumeration order is unspecified; sort the keys when order matters.
  • Empty pieces from Split(' '). They become empty-string keys or crash int.Parse.

Your exercise

The starter splits the input line into words for you. Count how often each distinct word occurs and print the results in the order the exercise asks for. The most likely mistakes are crashing on the first occurrence of a word and printing in the dictionary's own order.

Up nextLINQ - Querying CollectionsCollections and LINQ

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…