Hashes and Symbols
Published: 2024-01-24 17:28:34

_Codecademy Cheatsheet_

**Ruby Symbols**

In Ruby, _symbols_ are immutable names primarily used as hash keys or for referencing method names.

```
my_bologna = {
  :first_name => "Oscar",
  :second_name => "Meyer",
  :slices => 12
}

puts my_bologna[:second_name] # => Meyer

```
<u>_Symbol Syntax_</u>
Symbols always start with a colon (`:`). They must be valid Ruby variable names, so the first character after the colon has to be a letter or underscore (`_`); after that, any combination of letters, numbers, and underscores is allowed.

Make sure you don’t put any spaces in your symbol name—if you do, Ruby will get confused.

```
:my symbol # Don't do this!
:my_symbol # Do this instead.

```
<u>_What are Symbols Used For?_</u>
Symbols pop up in a lot of places in Ruby, but they’re primarily used either as hash keys or for referencing method names.

```
sounds = {
  :cat => "meow",
  :dog => "woof",
  :computer => 10010110,
}
```
Symbols make good hash keys for a few reasons:

1. They’re immutable, meaning they can’t be changed once they’re created;
2. Only one copy of any symbol exists at a given time, so they save memory;
3. Symbol-as-keys are faster than strings-as-keys because of the above two reasons.

---
**Ruby Hashes, Symbols, & Values**

In Ruby hashes, key symbols and their values can be defined in either of two ways, using a `=>` or `:` to separate symbol keys from values.

```
my_progress = {
  :program => "Codecademy",
  :language => "Ruby",
  :enthusiastic? => true 
}
#Key symbols and their values can be defined with a =>, also known as a hash rocket.

my_progress = {
  program: "Codecademy",
  language: "Ruby",
  enthusiastic?: true 
}
#Key symbols and their values can also be defined with the colon (:) at the end of the symbol followed by its value.
```
---

**Converting Between Symbols and Strings**

Converting between strings and symbols is a snap.

```
:sasquatch.to_s
# ==> "sasquatch"

"sasquatch".to_sym
# ==> :sasquatch
```
The `.to_s` and `.to_sym` methods are what you’re looking for!

```
strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]

symbols = []

strings.each do |s|
 symbols.push(s.to_sym)
end
print symbols
```
Besides using `.to_sym`, you can also use `.intern`. This will internalize the string into a symbol and works just like `.to_sym`:

```
"hello".intern
# ==> :hello

```
Ruby’s `.to_sym` method can convert a string to a symbol, and `.to_i` will convert a string to an integer.

---
**Ruby .select Method**
In Ruby, the `.select` method can be used to grab specific values from a hash that meet a certain criteria.

```
olympic_trials = {
  Sally: 9.58,
  John: 9.69,
  Bob: 14.91
}

olympic_trials.select { |name, time| time <  10.05 }
#The example above returns {:Sally=>9.58, :John=>9.69} since Sally and John are the only keys whose values meet the time < 10.05 criteria.

```

---
**Ruby .each_key & .each_value**

In Ruby, the `.each_key` and `.each_value` methods are used to iterate over only the keys or only the values in a hash

```
my_hash = { one: 1, two: 2, three: 3 }

my_hash.each_key { |k| print k, " " }
# ==> one two three

my_hash.each_value { |v| print v, " " }
# ==> 1 2 3
```

---

**The Case Statement**

`if` and `else` are powerful, but we can get bogged down in i`f`s and `elsif`s if we have a lot of conditions to check. Thankfully, Ruby provides us with a concise alternative: the `case` statement. The syntax looks like this:

```
case language
  when "JS"
    puts "Websites!"
  when "Python"
    puts "Science!"
  when "Ruby"
    puts "Web apps!"
  else
    puts "I don't know!"
end
```
---

**A NIGHT AT THE MOVIES**


```
movies = {
  harry_potter: 4
}
puts "What would you like to do?"

choice = gets.chomp

case choice
 when "add"
   puts "What movie would you like to add?"
   title = gets.chomp
   if movies[title.to_sym].nil?
   puts "What rating does the movie have? (Type a number from 0 to 4)"
   rating = gets.chomp
   movies[title.to_sym] = rating.to_i
   puts "#{title} was added with a rating of #{rating}!"
   else 
   puts "That movie already exists! Its rating is #{movies[title.to_sym]}'"
   end
 when "update"
   puts 'What movie would you like to update?'
   title = gets.chomp
   if movies[title].nil?
   puts "There has been an error! Please check the spelling again."
   else
   puts "What is the new rating?"
   rating = gets.chomp
   movies[title.intern] = rating.to_i
   puts "#{title} has been updated with new rating of #{rating}."
   end
 when "display"
   movies.each { |movie, rating| 
   puts "#{movie}: #{rating}"}
 when "delete"
   puts "What is the title of the movie you would like to delete?"
   title = gets.chomp
   if movies[title.intern].nil?
   puts "The movie was not found"
   else
   movies.delete(title.to_sym)
   puts "#{title} has been removed."
   end
 else 
 puts "Error!"
end 
```