Introduction
In this write-up, we will continue with my previous article and will explore more collections in Ruby on Rails. I hope it will help you to dive deep into Ruby. Here is the link to my previous article.
What we will learn here?
- Hashes and Symbols.
- Hashes.
- Symbols.
- Methods of Hashes.
- Nested Arrays.
- Nested Hashes.
- Iterators.
- Letter Frequency Counter.
Hashes & Symbols
Hashes
- Hashes (sometimes known as associative arrays, maps, or dictionaries) are similar to arrays; they are an indexed collection of elements.
- However, while you index the arrays with integers, you can index a hash with a key or string. That is very useful when you want to map values. For example, “name” => “David”.
- Here, “name” is the index (also called the key) which is mapped to the value “David”.
- So, hashes represent key=>value
- A hash is created with comma separated keys and values inside the curly brackets.
Example
- As you can see, the values are accessed using the same index syntax as with an array.
- Compared with arrays, hashes have one significant advantage: they can use any object as an index, even an array. For example - { [1,”jan”] => “January” }.
Symbols
- In the previous example, we used strings as keys for the hash, but Ruby has a more elegant and faster way for creating and accessing hash index than using strings.
- Symbols are similar to strings to strings, but they are immutable, meaning they cannot be changed.
- A Symbol is created using a colon and a name, for example -
Syntax
a = id
- In the code above, id is a symbol.
- You can also think of id as the name of the variable id, and plain id as the value of the variable.
- Using symbols not only saves time when doing comparisons, but also saves the memory because they are stored only once.
- Uses of symbols include using them as hash keys.
Example
In the code above, symbols are used as keys for our hash.
Methods of Hashes
- delete (key) removes the key-value pairs from the hash by key.
- key (value) returns the key for the given value in the hash; nil if no matching value is found.
- invert creates a new hash, reversing keys and values from hash; that is in the new hash, the keys from hash become values and values become keys.
- keys return a new array with keys from the hash.
- values return a new array containing all the values of the hash.
- length returns the length of hash as an integer.
Example
Nested Arrays
Arrays can contain other arrays. These are called nested arrays.
Example
Note
The arr array contains two arrays. So, arr[1][2] accesses the second array’s third element, which is 6.
- Nested Hashes
- Hashes can also be nested.
Example
Hashes and arrays can have any level of nesting, but keep in mind that hashes and arrays with more than three dimensions are harder to manage.
Iterators
- As we seen in the previous lessons, we can loop over arrays and hashes using for
- Ruby provides more elegant looping methods called
- Iterators are used to create loops.
- Each iterator is one of the most used ones.
Example
Note
Here, x denotes the elements of arrays.
- The syntax might seem confusing at first, but you just need to remember the pipe symbols around the variable.
- Each iterator loops through all elements of the array and assigns the corresponding element to the variable inside the pipes with each iteration.
- This variable is called block parameter. We can, for eg: calculate the sum of all elements.
Example
The Each iterator can also be used with hashes.
Example
- In the example above, key and value are variables that get assigned to the corresponding values of the hash elements at each iteration.
- You can use any name for your variables.
- The do and end keywords specify a block of code in Ruby.
- After the opening of the block, we have the block parameters within pipes (||).
- Ruby provides a shorthand way of writing blocks: you can use Curly braces to start and end code blocks.
Example
- The Each iterator can also be used on ranges.
- For Strings, you can use the each_char iterator to iterate over the characters.
- There are also iterators available for numbers.
- The Times iterator executes a loop the specified number of times.
Example
Letter Frequency Counter
Letter Frequency
Let’s create a program that will count the frequency of letters (numbers of occurrences) in a given string. First, we need a string.
Example
- Text = “I am learning Ruby and it is fun!”
- Text.downcase!
- The downcase! Method is used to convert all letters in the string to lowercase.
- Next, we will need a hash to hold the letters as keys and the frequency of the letters as their corresponding values.
- For that, we need to create an empty hash and set the default value for all values to 0.
Example
- Freqs = {}
- Freqs.default = 0
- The default method is used to set the default value for the hash, meaning that any key that does not have a value assigned will be set to that values.
- Next, we will need to iterate over each character in the string and calculate the number of occurrences in the hash.
- We can do that using the each_char
Example
- Text.each_char{|char| freqs[char] + = 1}
- During each iteration, the char variable is assigned the corresponding character in our text string and then the value of that character’s frequency is incremented in the freqs
- So, for example, if the letter “c” appears twice in the text, freqs[“c”] will be equal to 2 after the iterator executes.
- So, freqs will hold all the characters of the string with their corresponding occurrence number.
- To show a nice result output in an alphabetic order, we can create a range of all letters and print their corresponding frequencies.
Example
- (“a”..”z”).each{|x| puts “
We do this because not all letters of the alphabet are contained in our text.
Example
Summary
Today, we learned some interesting concepts. In the future, we will see some more on this. If you have any queries, please ask me.