Skip to content

Commit aced6ca

Browse files
committed
Add concept and exercise
1 parent c268be8 commit aced6ca

File tree

13 files changed

+1042
-39
lines changed

13 files changed

+1042
-39
lines changed

concepts/hashes/.meta/config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"blurb": "Hashes are collections of key-value pairs, where each unique key maps to a specific value. They are useful for storing and retrieving data based on keys rather than numerical indices.",
3+
"authors": ["meatball133"],
4+
"contributors": ["kotp"]
5+
}

concepts/hashes/about.md

Lines changed: 192 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,203 @@
11
# About
22

3-
## Creating hashes
3+
[Hashes][hash] are also known as dictionary or map in other languages, they are a mutable unsorted collection which maps keys to values.
4+
Each key is unique and is used to retrieve the corresponding value.
5+
The keys can be of any data type which is hashable (has a `hash` method), this includes strings, numbers, and most data types and objects in Ruby.
46

7+
Even though Hashes are unordered collections, [Ruby maintains the insertion order of key-value pairs][entry_order].
8+
This means that when you iterate over a `Hash`, the pairs will be returned in the order they were added.
9+
However, deleting elements may affect the order of remaining elements.
10+
Hashes behavior of maintaining insertion order was introduced in Ruby [1.9][ruby-1.9].
511

12+
## Creating Hashes
613

7-
## Indexing
14+
You can create a `Hash` using curly braces `{}` with key-value pairs formed as `key => value` and separated by commas:
15+
16+
```ruby
17+
my_hash = {"name" => "Alice", "age" => 30, "city" => "New York"}
18+
```
19+
20+
You can also mix and match different types of keys and values:
21+
22+
```ruby
23+
my_hash = {1 => "one", :two => 2, "three" => [3, "three"]}
24+
```
25+
26+
Alternatively if the keys are symbols, you can use a more the newer syntax which was introcued in Ruby 1.9:
27+
28+
```ruby
29+
my_hash = {name: "Alice", age: 30, city: "New York"}
30+
```
31+
32+
You can create an empty `Hash` using the `Hash.new` method:
33+
34+
```ruby
35+
empty_hash = Hash.new
36+
```
37+
38+
## Accessing values
39+
40+
You can access values in a `Hash` instance using its corresponding keys, the syntax reminds of array indexing, but using the key instead of an index:
41+
42+
```ruby
43+
my_hash = {"name" => "Alice", "age" => 30, "city" => "New York"}
44+
my_hash["name"]
45+
# => "Alice"
46+
```
47+
48+
If the key does not exist in the `Hash` instance, the `[]` method will return `nil`:
49+
50+
```ruby
51+
my_hash = {"name" => "Alice", "age" => 30}
52+
my_hash["city"]
53+
# => nil
54+
```
55+
56+
If the disired behavior is to not return `nil` for non-existing keys, another way of accessing values is by using the [`fetch`][fetch] method, which allows you provide a default value for non-existing keys.
57+
If the `fetch` method is used without a default value and the key does not exist, it will raise a `KeyError` exception.
58+
59+
```ruby
60+
my_hash = {"name" => "Alice", "age" => 30}
61+
my_hash.fetch("city", "Unknown")
62+
# => "Unknown"
63+
64+
my_hash.fetch("city")
65+
# => KeyError: key not found: "city"
66+
```
867

968
## Modifying
1069

70+
You can add or update key-value pairs in a `Hash` instance by assigning a value to a key using the assignment operator `=`.
71+
Assigning a value to an existing key will update the value, while assigning a value to a new key will add a new key-value pair:
72+
73+
```ruby
74+
my_hash = {"name" => "Alice", "age" => 30}
75+
my_hash["city"] = "New York"
76+
my_hash["age"] = 31
77+
78+
my_hash
79+
# => {"name" => "Alice", "age" => 31, "city" => "New York"}
80+
```
81+
82+
## Default values
83+
84+
When fetching a value with `[]` for a key that does not exist in the `Hash` instance, Ruby returns `nil` by default.
85+
86+
```ruby
87+
my_hash = {"name" => "Alice"}
88+
my_hash["age"]
89+
# => nil
90+
```
91+
92+
This might not always be desirable, so you can set a default value for the `Hash` instance using `Hash.new(default_value)`.
93+
See that the default value is returned only for keys that do not exist in the `Hash` instance.
94+
95+
```ruby
96+
my_hash = Hash.new("unknown")
97+
my_hash["name"] = "Alice"
98+
my_hash["age"]
99+
# => "unknown"
100+
101+
my_hash["name"]
102+
# => "Alice"
103+
```
104+
105+
~~~~exercism/note
106+
Be cautious when using mutable objects (like Arrays or other Hashes) as default values, as they can lead to unexpected behavior.
107+
~~~~
108+
109+
## Deleting key-value pairs
110+
111+
You can delete a key-value pair from a `Hash` instance using the [`delete`][delete] method, which takes the key as an argument:
112+
113+
```ruby
114+
my_hash = {"name" => "Alice", "age" => 30, "city" => "New York"}
115+
my_hash.delete("age")
116+
my_hash
117+
# => {"name" => "Alice", "city" => "New York"}
118+
```
119+
11120
## Methods
12121

13-
has_value?
14-
include?
122+
There are several useful instance methods available for Hashes in Ruby.
123+
Here are some commonly used ones:
124+
125+
### `has_value?` and `include?`
126+
127+
You can check if a `Hash` instance contains a specific value using the [`has_value?`][has_value?] method.
128+
129+
```ruby
130+
my_hash = {"name" => "Alice", "age" => 30}
131+
my_hash.has_value?(30)
132+
# => true
133+
my_hash.has_value?(25)
134+
# => false
135+
```
136+
137+
You can check if a `Hash` instance contains a specific key using the [`include?`][include?] method.
138+
139+
```ruby
140+
my_hash = {"name" => "Alice", "age" => 30}
141+
my_hash.include?("name")
142+
# => true
143+
my_hash.include?("city")
144+
# => false
145+
```
146+
147+
### `keys` and `values`
148+
149+
You can retrieve all the keys of a `Hash` instance using the [`keys`][keys] method, which returns an array of keys.
150+
151+
```ruby
152+
my_hash = {"name" => "Alice", "age" => 30}
153+
my_hash.keys
154+
# => ["name", "age"]
155+
```
156+
157+
You can retrieve all the values of a `Hash` instance using the [`values`][values] method, which returns an array of values.
158+
159+
```ruby
160+
my_hash = {"name" => "Alice", "age" => 30}
161+
my_hash.values
162+
# => ["Alice", 30]
163+
```
164+
165+
## Iterating over Hashes
166+
167+
You can iterate over the key-value pairs in a `Hash` instance using the `each_pair` method.
168+
This will give you access to both the key and the value for each pair:
169+
170+
```ruby
171+
my_hash = {"name" => "Alice", "age" => 30}
172+
my_hash.each_pair do |key, value|
173+
puts "#{key}: #{value}"
174+
end
175+
# Output:
176+
# name: Alice
177+
# age: 30
178+
```
179+
180+
You can also iterate over just the keys or just the values using the [`each_key`][each_key] or [`each_value`][each_value] methods, respectively:
181+
182+
```ruby
183+
my_hash = {"name" => "Alice", "age" => 30}
184+
my_hash.each_key do |key|
185+
puts key
186+
end
187+
# Output:
188+
# name
189+
# age
190+
```
15191

16-
keys
17-
values
192+
[entry_order]: https://docs.ruby-lang.org/en/master/Hash.html#class-Hash-label-Entry+Order
193+
[each_pair]: https://docs.ruby-lang.org/en/master/Hash.html#method-i-each_pair
194+
[each_key]: https://docs.ruby-lang.org/en/master/Hash.html#method-i-each_key
195+
[keys]: https://docs.ruby-lang.org/en/master/Hash.html#method-i-keys
196+
[each_value]: https://docs.ruby-lang.org/en/master/Hash.html#method-i-each_value
197+
[values]: https://docs.ruby-lang.org/en/master/Hash.html#method-i-values
198+
[has_value?]: https://docs.ruby-lang.org/en/master/Hash.html#method-i-has_value-3F
199+
[include?]: https://docs.ruby-lang.org/en/master/Hash.html#method-i-include-3F
200+
[hash]: https://docs.ruby-lang.org/en/master/Hash.html
201+
[fetch]: https://docs.ruby-lang.org/en/master/Hash.html#method-i-fetch
202+
[delete]: https://docs.ruby-lang.org/en/master/Hash.html#method-i-delete
203+
[ruby-1.9]: https://ruby-doc.org/3.4/NEWS/NEWS-1_9_1.html

0 commit comments

Comments
 (0)