Hashes and symbols in Ruby
Tags: ruby
Published: 2018-10-11 16:54:49

---
title: Hashes and symbols in Ruby
published: true
description: 
tags: ruby
---

## Introduction

In this article, we'll keep exploring hashes and we'll discover what symbols are. For a refresher on hashes, I wrote <a href="https://dev.to/damcosset/arrays-and-hashes-in-ruby-3h5h">this</a>.


### Introduction to *nil*

In Ruby, *nil* is a way to say that a value doesn't exist. So, if we have a Hash and we try to access a value that doesn't exist:


```ruby
my_hash = {
	"name" => "Damien",
	"age" => 26,
	"nationality": "French"
}

puts my_hash["lastName"] # puts nothing, because nil. lastName key doesn't exist

```

No error thrown, Ruby just tells you that nothing exists there by telling you... nothing :D

However, you can specify a default value in a Hash. That default value will be returned instead of nil when Ruby doesn't find a value inside a Hash:

```ruby
with_default = Hash.new("No value found here!!!")

puts with_default["name"]  # puts "No value found here!!!"
puts with_default[42] # puts "No value found here!!!"

```

## Symbols

Let's start with the syntax. Symbols always start with a colon *:* and they must be a valid variable name:

```ruby
my_symbol = :this_is_a_symbol
```

Symbols can be used as hash keys or to reference a method's name.

### Hash's key

Symbols are a good use for hash keys because they are immutable. You can't change a symbol once its defined. Only one copy of a symbol can exist at one time, so they do not consume a lot of memory. These two reasons makes symbols as keys faster than strings as keys.

```ruby
my_hash = {
	:one => "One",
	:a_symbol => 42,
	:boom => true
}

puts my_hash
# {:one=>"One", :a_symbol=>42, :boom=>true}
```

#### Converting between symbols and strings.

Ruby provides methods to convert a symbol to a string and vice versa. The method *.to_s* converts a symbol to a string while *.to_sym* does the opposite. The method *.intern* does the same thing than *.to_sym*

```ruby
puts :this_is_my_shiny_symbol.to_s # this_is_my_shiny_symbol
puts "look_at_this_string".to_sym # :look_at_this_string
puts "HelloWorld".intern # :HelloWorld
```

#### Hash rocket syntax

You saw that we used a *=>* between the key and the value in a hash. This is called the hash rocket syntax. However, you can also use a shorter syntax. To do so, remove the *=>* and place the colon at the end of the symbol. The syntax resembles a javascript object now:

```ruby
symbols_as_keys = {
	one: "two",
	three: "four"
}

```

The keys are still symbols. However, this syntax doesn't work with strings as keys.


### Be more selective

We can grab a value from a hash when we have its associated key. But how would we filter a hash to only retrieve values that meet some criteria? We could use *.select*


```ruby
restaurant_ratings =  {
	soleia: 6,
	auberge_du_printemps: 3,
	pauls: 4,
	olive_garden: 7
}
```

Let's use select to filter restaurants with a rating strictly superior to 5.

```ruby
puts restaurant_ratings.select{ |restaurant, rating|
 rating > 5
}

# {:soleia=>6, :olive_garden=>7}
```

Now, let's get the restaurants where the rating is equal to 3

```ruby

puts restaurant_ratings.select{ |restaurant, rating| 
  rating == 3
}

# {:auberge_du_printemps=>3}`
```

### Just the keys? Or just the values

Because Ruby is awesome, you do not need to iterate over keys *AND* values if you don't need one of them. With *.each_key*, you'll iterate only over the keys and with *.each_value*, you will get only the values:

```ruby
restaurant_ratings.each_key{|k| puts k}

# soleia
# auberge_du_printemps
# pauls
# olive_garden


restaurant_ratings.each_value{|v| puts v}

# 6
# 3
# 4
# 7

```