Programming Fundamentals - Part 3 - Lists

So far (parts 1 & 2) we have talked about the basic building blocks of basically every programming language – the primitive types: String, Number, Boolean – but just using these types doesn't allow our application to be that sophisticated. A typical business application involves more complex data – apartments for rent, customer profiles, orders, etc – so we have to learn about a couple more advanced data types that better encapsulate the complexities of real-world data.

Lists

In daily life, lists are all around us.  Grocery lists.  To-do lists.  A dinner recipe might have two lists: one for the ingredients, and one for the cooking instructions.  Your bookshelf is a list of books.  There's a stack of plates in your cupboard.  An analog clock displays a circularly-arranged list of numbers on its face.

Most of computer programming boils down to managing a bunch of lists.  You can see this every day on the internet.  Just visit your favorite website and lists will appear like stars in the night sky: the longer you look, the more you'll see.

Consider:

  • The navigation bar at the top of this site is a list of links.
  • This bullet list is, well, a list.
  • Go to your Amazon order history.  Yup, it's a list.
  • Google for something.  You get a list.
  • Go to your Instagram feed or Twitter page.  Lots of lists.

It behooves us, then, to be comfortable with how to manage lists with Ruby.

If you haven't already done so, go to this lesson's repository and open it in Gitpod.  Then, in the code-along directory, open the file 3-arrays.rb.

In Ruby, the basic list data type is called an Array.  Let's take a look at some arrays.  Enter the following in the file and the run it (ruby 3-arrays.rb):

favorite_foods = ["tacos", "pizza", "ice cream"]
puts favorite_foods

we_have_to_go_back = [4, 8, 15, 16, 23, 42]
puts we_have_to_go_back

mixed_array = ["tacos", 12, true]
puts mixed_array

Notice how we use square brackets [ ] to enclose the list of items, and we use commas to separate each item.

The first array holds 3 strings.  The second array holds 6 integers.  And the third array holds a string, an integer, and a boolean!  (Note: many languages require that all elements of an array have the same type, but ruby is more forgiving.)

The elements of an array can be anything, even other arrays.  Add this code:

shopping_lists = [["milk", "eggs", "toilet paper"], ["soap", "shampoo", "shaving cream", "toilet paper"]]
puts shopping_lists

Here we have an array named shopping_lists with 2 elements.  Those elements are each an array consisting of 3 and 4 elements respectively.  Lists of lists.

Accessing Elements within Arrays

An array is a list of elements and those elements are in a known order.  The order becomes important when accessing a specific element in the array. You'll need to know the position of the object (i.e. where it is in the order) to access it. The position is also known as the index.  We use square brackets [ ] around the index in order to retrieve an item.  For example, if we want the first element from the favorite_foods array:

first_favorite_food = favorite_foods[0]
puts first_favorite_food

The first element in an array is at index 0, the second element is 1, the third element is 2 and so on.  Computers like to start counting at 0, so this numbering is common in many programming languages.  If we want the second element from our favorite foods array, we'd use favorite_foods[1].  And the third, favorite_foods[2].  What about the fourth?  The array only has 3 elements, so what happens when we check the 4th position:

puts favorite_foods[3]

You might have expected an error, but the result is nothing - there's no data at that position, so the result is nothing.  To be more specific, the result is nil, another data type representing the absence of data.  But when we try to display nil, the output is just blank.

Let's practice with the shopping_lists array.  What's the third element in the second shopping list?

shopping_lists[1][2]

It might help to break this down into a couple steps:

second_shopping_list = shopping_lists[1]
third_item = second_shopping_list[2]
puts third_item

Modifying Arrays

Once an array exists, we often want to add to it.

When we say some data is a String or an Integer or an Array, that means the data's classification is a String or an Integer or an Array.  Every class has built-in functionality, or methods.  We already saw this when we wanted to convert a number into a string: 3.to_s becomes "3".

To add an element to an array, we need to use its built-in push method:

favorite_foods.push("more tacos")
puts favorite_foods

The push method takes a single argument which is the element to be added to the end of the array.  Notice that the we have the data object, then a period, then the method.  This is called dot-notation and it's how we'll call all sorts of methods as our code gets more and more complex.

The push method has an alternative that you might see in your Google searches:

favorite_foods << "more tacos"

This uses the shovel operator (<<), but it does the same thing.

We can also combine multiple arrays together:

favorite_foods = favorite_foods + ["french fries", "ramen"]
puts favorite_foods

full_shopping_list = shopping_lists[0] + shopping_lists[1]
puts full_shopping_list

Note that both things being combined using + are arrays.  You can't combine an array and a single element.  But don't take our word for it.  Try it yourself to confirm.

Length of an Array

Another built-in method that we often use with arrays is length.  We frequently need to know how many elements are in an array.  To do so, add the following code:

puts favorite_foods.length
puts favorite_foods.count
puts favorite_foods.size

Here we have 3 Array methods which all do the same thing.  Why?  Because ruby goes out of its way to be expressive - sometimes it will make more sense to think about the "count" of elements in an array, and other times the "size" of the array be a more useful concept.  In ruby, we get the luxury of deciding which will make our code more clear.

Other Methods

We've just scratched the surface of what we can do with arrays.  To find out what else is possible, check out the Array class documentation: https://ruby-doc.org/core-2.7.0/Array.html.

Lab

Time for a lab to practice working with arrays. Instructions are in the file 3-arrays.rb in the labs directory.