|
| 1 | +--- |
| 2 | +tags: |
| 3 | +- datatypes/collections |
| 4 | +- oop |
| 5 | +--- |
| 6 | + |
| 7 | +# Dictionaries |
| 8 | + |
| 9 | +## Introduction |
| 10 | + |
| 11 | +### Abstract Data Type |
| 12 | + |
| 13 | +A *dictionary*, also called a *hash*, a *map*, or a *hashmap*, is a key-value store: it stores values (that can be of any type) and indexes them using a key (which is in general of a simple type, such as `int`). |
| 14 | + |
| 15 | +Described [abstractly](./lectures/data/intro#abstract-data-types), [a dictionary](https://en.wikipedia.org/wiki/Hash_table)) is |
| 16 | + |
| 17 | +- a finite collection of elements, |
| 18 | +- in *no* particular order, |
| 19 | +- that may contain the same element multiple times. |
| 20 | + |
| 21 | +The fact that it may contain the same element multiple times makes it different from a set, the fact that it is ordered makes it different from a [multiset](https://en.wikipedia.org/wiki/Multiset). |
| 22 | + |
| 23 | +Generally, it has operations to… |
| 24 | + |
| 25 | +- … create an empty dictionary, |
| 26 | +- … test for emptiness, |
| 27 | +- … insert or update a value, |
| 28 | +- … remove a key-value pair, |
| 29 | +- … test for existence of a key. |
| 30 | + |
| 31 | +### Difference with array |
| 32 | + |
| 33 | +Dictionaries serve a similar purpose to arrays, but with a few notable differences: |
| 34 | + |
| 35 | +- Values do not have a particular order, |
| 36 | +- Keys are more complicated than integers, |
| 37 | +- Dictionaries automatically expand and shrink when values are added or removed. |
| 38 | + |
| 39 | +<!-- |
| 40 | +
|
| 41 | +### Difference with lists |
| 42 | +
|
| 43 | +However, stacks have difference with lists: |
| 44 | +
|
| 45 | +- Only the top element's value can be read (accessed), |
| 46 | +- Adding and removing can only be done "on the right side", that is, at the top of the stack. |
| 47 | +
|
| 48 | +## Possible Implementation |
| 49 | +
|
| 50 | +
|
| 51 | +
|
| 52 | +Arrays |
| 53 | + arrays and dictionaries both store collections of data, but differ by how they are accessed. Items in an array are accessed by position (often a number) and hence have an order. Items in a dictionary are accessed by key and are unordered. |
| 54 | +
|
| 55 | +
|
| 56 | +
|
| 57 | +An array can contain more than simple datatypes: it can contain objects. |
| 58 | +It can be objects from a custom class, or even … arrays, which are themselves objects! |
| 59 | +
|
| 60 | +## Array of Objects From a Custom Class |
| 61 | +
|
| 62 | +In the following example, we will ask the user how many `Item` objects (the details of the implementation do not matter, but can be [inspired by this example](./lectures/flow/control_flow_and_classes#setters-with-input-validation)) they want to create, then fill an array with `Item` objects initialized from user input: |
| 63 | +
|
| 64 | +``` |
| 65 | +Console.WriteLine("How many items would you like to stock?"); |
| 66 | +Item[] items = new Item[int.Parse(Console.ReadLine())]; |
| 67 | +int i = 0; |
| 68 | +while(i < items.Length) |
| 69 | +{ |
| 70 | + Console.WriteLine($"Enter description of item {i+1}:"); |
| 71 | + string description = Console.ReadLine(); |
| 72 | + Console.WriteLine($"Enter price of item {i+1}:"); |
| 73 | + decimal price = decimal.Parse(Console.ReadLine()); |
| 74 | + items[i] = new Item(description, price); |
| 75 | + i++; |
| 76 | +} |
| 77 | +``` |
| 78 | +
|
| 79 | +Observe that, since we do not perform any user-input validation, we can simply use the result of `int.Parse()` as the size declarator for the `items` array - no `size` variable is needed at all. |
| 80 | +
|
| 81 | +We can also use `while` loops to search through arrays for a particular value. For example, this code will find and display the lowest-priced item in the array `items`, which was initialized by user input: |
| 82 | +
|
| 83 | +``` |
| 84 | +Item lowestItem = items[0]; |
| 85 | +int i = 1; |
| 86 | +while(i < items.Length) |
| 87 | +{ |
| 88 | + if(items[i].GetPrice() < lowestItem.GetPrice()) |
| 89 | + { |
| 90 | + lowestItem = items[i]; |
| 91 | + } |
| 92 | + i++; |
| 93 | +} |
| 94 | +Console.WriteLine($"The lowest-priced item is {lowestItem}"); |
| 95 | +``` |
| 96 | +
|
| 97 | +Note that the `lowestItem` variable needs to be initialized to refer to an `Item` object before we can call the `GetPrice()` method on it; we cannot call `GetPrice()` if `lowestItem` is `null`. We could try to create an `Item` object with the "highest possible" price, but a simpler approach is to initialize `lowestItem` with `items[0]`. As long as the array has at least one element, `0` is a valid index, and the first item in the array can be our first "guess" at the lowest-priced item. |
| 98 | +
|
| 99 | +## Arrays of Arrays |
| 100 | +
|
| 101 | +An array of arrays is called a multi-dimensional array. |
| 102 | +A multi-dimensional array can be rectangular (it then represents an $n$-dimensional block of memory) or jagged (in that case, it is an array of arrays). |
| 103 | +
|
| 104 | +### Rectangular Multi-Dimensional Array |
| 105 | +
|
| 106 | +Also called $2$-dimensional arrays, their syntax is very close to that of $1$-dimensional arrays: |
| 107 | +
|
| 108 | +``` |
| 109 | +int[,] matrix = new int[2, 3]; |
| 110 | +``` |
| 111 | +
|
| 112 | +where `2` is the number of rows, and `3` is the number of columns. |
| 113 | +They can be accessed with `matrix.GetLength(0)` and `matrix.GetLength(1)` respectively. |
| 114 | +
|
| 115 | +Assignment is as for $1$-dimensional arrays, starting at $0$: |
| 116 | +
|
| 117 | +``` |
| 118 | +matrix[0, 0] = 1; |
| 119 | +matrix[0, 1] = 2; |
| 120 | +matrix[0, 2] = 3; |
| 121 | +matrix[1, 0] = 4; |
| 122 | +matrix[1, 1] = 5; |
| 123 | +matrix[1, 2] = 6; |
| 124 | +``` |
| 125 | +
|
| 126 | +This will produce a matrix as follows: |
| 127 | +
|
| 128 | + | 0th col. | 1st col. | 2nd col. | |
| 129 | +------- | :---: | :---: | :---: | |
| 130 | +0th row | 1 | 2 | 3 | |
| 131 | +1st row | 4 | 5 | 6 | |
| 132 | +
|
| 133 | +We could also have used a shortened notation to declare this $2$-dimensional array, as follows: |
| 134 | +
|
| 135 | +``` |
| 136 | +int[,] matrix = new int[,] |
| 137 | +{ |
| 138 | + {1,2,3}, |
| 139 | + {4,5,6} |
| 140 | +}; |
| 141 | +``` |
| 142 | +
|
| 143 | +or even simply |
| 144 | +
|
| 145 | +``` |
| 146 | +int[,] matrix = {{1,2,3},{4,5,6}}; |
| 147 | +``` |
| 148 | +
|
| 149 | +To display such an array, nested loops are needed: |
| 150 | +
|
| 151 | +``` |
| 152 | +for (int row = 0; row < matrix.GetLength(0); row++) |
| 153 | +{ |
| 154 | + for (int col = 0; col < matrix.GetLength(1); col++) |
| 155 | + Console.Write(matrix[row, col] + " "); |
| 156 | + Console.WriteLine(); |
| 157 | +} |
| 158 | +``` |
| 159 | +
|
| 160 | +### Jagged Array |
| 161 | +
|
| 162 | +A jagged array is an array of arrays. |
| 163 | +The difference from rectangular arrays is that the arrays stored can be of varying sizes. The syntax of a jagged array is as follows: |
| 164 | +
|
| 165 | +``` |
| 166 | +int [][] jaggedArray = new int[3][]; |
| 167 | +``` |
| 168 | +
|
| 169 | +Here, `3` is the number of rows, but the number of columns is not included: this is because the stored arrays are different sizes, so the number of columns will vary depending on the row. |
| 170 | +
|
| 171 | +The syntax is straightforward once understood that jagged arrays are *exactly* arrays of arrays: |
| 172 | +
|
| 173 | +``` |
| 174 | +!include code/snippets/jaggedArray.cs |
| 175 | +``` |
| 176 | +
|
| 177 | +In this example, it should be clear that `jaggedArray[row]` is itself an array, and hence that we can use e.g., `jaggedArray[row].Length` or `jaggedArray[row][arrayCell]`. |
| 178 | +
|
| 179 | +### Deciding Between Rectangular and Jagged Arrays |
| 180 | +
|
| 181 | +The main distinction between rectangular and jagged arrays is that the former is more consistent with its sizing--in other words, in a rectangular array, each array housed within it will be the same size in every row, by definition. In contrast, jagged arrays are not as consistent. This can be seen in the difference between how rectangular and jagged arrays are initialized. Recall that, when initializing a rectangular array, the number of rows and columns is required, but only the number of rows is required for a jagged array. |
| 182 | +
|
| 183 | +Therefore, when deciding which type of array to use in a given situation, you will want to base it off of whether you need an array that is predictable in its sizing. If you want to make a table where most or every cell will be filled, a rectangular array will make more sense, whereas a jagged array will be preferred when the number of entries per row could be highly variable or difficult to predict. |
| 184 | +
|
| 185 | +Rectangular arrays work well when creating a matrix (an array of numbers used in mathematics, especially in linear algebra) or a table/spreadsheet of data where the number of data points (and, therefore, the number of columns) is consistent in each row. Jagged arrays work well when the number of data points varies. A good example would be if you want to use an array to store the time it takes you to run a lap. If you run the same number of laps every single time you run, without fail, then a rectangular array may work here. However, the more likely scenario is that the number will vary. In this case, a jagged array is better: the array in each row will be whatever size it needs to be in order to accommodate all of the data. |
| 186 | +--> |
0 commit comments