Back-end Engineering Articles

I write and talk about backend stuff like Ruby, Ruby On Rails, Databases, Testing, Architecture / Infrastructure / System Design, Cloud, DevOps, Backgroud Jobs, some JS stuff and more...

Github:
/danielmoralesp
Twitter:
@danielmpbp

2024-10-15

Ruby Arrays

Previously I wrote a blog post about the basic data types in Ruby: Strings, Numbers and Booleans. Also in the post called Ruby Each Loop we introduced the concept of Ruby Arrays, however not in great detail. This blog post will explain in detail what the Ruby Array data types are and how it can help us. 

Arrays

Array is a data type in Ruby. An array is a container of other ruby data type elements. The syntax starts with an open square bracket “[“ then inside of it we put the elements separated by comma and finally closing the array with a closed square bracket “]”. So:

  • * An array is an ordered set of objects in Ruby. 
  • * An array begins and ends with square brackets ([ and ]).
  • * Each item is separated by a comma (e.g. 67, 68).
  • * It is considered good practice to add a space after the comma. 



Examples:


2.6.8 :001 > numbers = [1, 2, 3, 4]
 => [1, 2, 3, 4]



An Array can contain more than just integer numbers. 

2.6.8 :004 > names = ["Chris", "Daniel", "Dakota", "Emily"]
 => ["Chris", "Daniel", "Dakota", "Emily"]



We have seen that arrays can contain integers and strings. Arrays can also contain other arrays!

2.6.8 :005 > age = [["Chris", 30], ["Daniel", 28], ["Dakota", 25], ["Emily", 26]]
 => [["Chris", 30], ["Daniel", 28], ["Dakota", 25], ["Emily", 26]]



Empty Array

So far we’ve seen arrays with values inside. But also it has a lot of sense to create empty arrays according to the use case we want to solve. An array does not always have to contain values. We can create empty arrays.  We usually do this because we plan to fill it later with data. 

2.6.8 :006 > empty_array = []
 => []


Growing the Array

We can add a single element to the array using the .append() method. The .append() statement always comes after the array. We cannot add more than one element to the array with .append(). If necessary, we call the .append() function multiple times.

2.6.8 :011 > empty_array = []
 => [] 
2.6.8 :012 > empty_array.append(1)
 => [1] 
2.6.8 :013 > empty_array.append(2)
 => [1, 2] 
2.6.8 :014 > empty_array.append(3)
 => [1, 2, 3]


As we can see, append helps us to add new elements to an array independently if the array is empty or if the array has one or more elements currently. It always appends at the end of the list the new element. Ruby has other way to add elements at the end of the array, is well know in the community and the symbol is “<<”

2.6.8 :034 > empty_array = []
 => [] 
2.6.8 :035 > empty_array << 1
 => [1] 
2.6.8 :036 > empty_array << 2
 => [1, 2] 
2.6.8 :037 > empty_array << 3
 => [1, 2, 3]



Is the same result but with less code. 

Concatenating 2 arrays in Ruby. 

Now we can have a use case where we have 2 different arrays and we want to join them. This is the way to do this.

2.6.8 :015 > empty_array = []
 => [] 
2.6.8 :016 > empty_array + [1]
 => [1] 
2.6.8 :017 > empty_array + [2, 3]
 => [2, 3] 
2.6.8 :018 > empty_array = []
 => [] 
2.6.8 :019 > empty_array += [1]
 => [1] 
2.6.8 :020 > empty_array += [2, 3]
 => [1, 2, 3]


We have the first option using the symbol “+”. But we’ve to take care of the current state of the array and not overwrite the current values. Let me explain. 


  • * In the last example of code we also started with an empty array. 
  • * Then used empty_array + [1] where [1] is an array of one element that we want to add to the original empty list
  • * However if we try to do the same operation but adding + [2, 3] the original value [1] will disappear. This is because we overwrite (re-assign) the original value.
  • * The solution is to use “+=” instead of just “+”. What does “+=”? This is a short operation for this: empty_array = empty_array + [2, 3]. As you can see we’re updating the current state of the array, not replacing the internal elements
  • * If we do the operation with “+=” the final list will be [1, 2, 3] instead of [2, 3] (without the 1)




Operations with Arrays

Now that we know how to create an array and how to grow it, we can start working with previously created arrays. 

The most important concept (and also one of the most wrong understood at the beginning) is that the arrays will always be indexed by zero. But what does this mean? Let me show you next diagram




Explain why the index of an array always starts from zero is something outside this post (however if you want to know why, here is a good blog post about it). What we are interested in here is how to access the internal elements of the array and how to do operations with them. 

The important thing here is to keep in mind that the first element of the array will be always indexed by zero.


Getting elements of the array

Given the fact that we can access elements by their index, we can start doing this:

2.6.8 :040 > new_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 
2.6.8 :041 > new_array[0]
 => 1


With this syntrax: array_name[index] we can access the individual element we want to extract from it. 

Also we can do something interesting if we want to explore how to access different elements depending on their position inside the array

2.6.8 :049 > new_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 
2.6.8 :050 > new_array[5]
 => 6 
2.6.8 :051 > new_array[15]
 => nil 
2.6.8 :052 > new_array[-1]
 => 12 
2.6.8 :053 > new_array[-2]
 => 11 
2.6.8 :054 > new_array[-3]
 => 10 
2.6.8 :055 > new_array[1, 3]
 => [2, 3, 4]


Let me explain each line of code here

  • * new_array[5] look for the element in the position number 5 in the array, which is 6
  • * new_array[15] look for the element in the position number 15 in the array, which does not exist, se we get nil
  • * new_array[-1] looks for the last element of the array, it doesn’t matter the position number. This is useful to get last element in large arrays
  • * new_array[-2] looks for the second last element of the array, it doesn’t matter the position number. This is useful to get last element in large arrays
  • * new_array[-3] looks for the third last element of the array, it doesn’t matter the position number. This is useful to get last element in large arrays
  • * new_array[1, 3] looks from position 1 to 3 in the array and slices them returning the values. 



Replacing elements

Now, what happens if I want to replace an element of the array? We’ve just to access it via the index and re-assign the value


2.6.8 :042 > new_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 
2.6.8 :043 > new_array[2] = "My Name"
 => "My Name" 
2.6.8 :044 > new_array
 => [1, 2, "My Name", 4, 5, 6, 7, 8, 9, 10, 11, 12]


As you can see with the syntax new_array[2] = "My Name" we are accessing the index number 2, which is the element with the value number 3 and we assign a new string with the value “My Name” and finally when we printed out the original array called new_array we get in the second position the new String. Awesome!

Iterating through an array

In a previous blog post we talked about the “.each” method which helps us to go through each element of the array and do something with them. 

2.6.8 :045 > new_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 
2.6.8 :046 > new_array.each do |element|
2.6.8 :047 >     puts element * 10
2.6.8 :048?>   end
10
20
30
40
50
60
70
80
90
100
110
120
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]


As you can see we go over each element of the array and multiply by 10 each element. 

Another useful way to iterate through each element is knowing the index position number of each element. We can do that like so:

2.6.8 :064 > new_array.each_with_index do |element, index|
2.6.8 :065 >     puts index
2.6.8 :066?>   puts element
2.6.8 :067?>   puts "----"
2.6.8 :068?>   end
0
1
----
1
2
----
2
3
----
3
4
----
4
5
----
5
6
----
6
7
----
7
8
----
8
9
----
9
10
----
10
11
----
11
12
----
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]



We can now see the index and the element printed out. 

This is the basics about Ruby Arrays, later we’ll be seeing more operations we can do

I hope you enjoyed the blog post

Thanks for reading!
DanielM