JumpStart Live Day 5: nil and Arrays

JSL Day 5 introduces the following topics:

  • nil
  • Arrays

nil

In Ruby, everything is an object — including nil.

Sometimes we create a variable without storing anything in them.  When a variable doesn’t have anything stored in it, it automatically has a value of nil.

The .nil? method lets us check if something is nil.

Let’s look at some examples!

nil_example1
Variables don’t automatically hold nil — they need to be declared first!

Things aren’t automatically nil in the beginning.

In this example, puts x triggers an error (instead of printing nil).

Why?  Because x hasn’t been declared.

For x to hold nil, we must declare it…without giving x the value we want.

Here’s an object that returns nil:

nil_example2
Checking if nums[1] returns nil
This code prints There is no value in index 1

nums[1] points to index position 1.  However, the single element in nums actually occupies position 0.

In other words, there is currently no value stored inside nums[1].  That’s why it returns nil.

But what happens if there is a value inside nums[1]?

nil_example3
Checking if nums[1] returns nil (it doesn’t!)
This time, nums has two elements — 1 (in position 0) and 2 (in position 1).

The thing inside nums[1] is 2.  …And so nums[1].nil? returns false.

As a result, our program executes the statement under else — and prints 2 is in index 1.

Arrays

Arrays are a container of things.  They are organized in order from first to last…with a 0-based index.  (Documentation here!)

Why Arrays?

Well, the alternative is to create individual variables.

That’s all well and good for smaller bits of data — but a huge pain if you’re, say…recording daily temperatures for the month of December.

Managing 31 separate variables just for temperatures would be annoying, sure.

But scale it to 365, 730, or 1,095.  Now you’ve got a real nightmare on your hands!

That’s where arrays come in handy.  We can easily assign all of December’s temperatures to a single name.  Best of all, we can access a specific day’s temperature if we need it.

Array Indices

An array’s index starts at 0, and increases by 1.

If you’re new to programming, that might sound weird.  (It did to me!)

Zed Shaw compares arrays to a deck of cards — because you can pick any element at random.  Consequently, having the indices start at 0 makes the math much easier in the long run.

arrays_index_example1
Accessing elements by index number

The array nums has three elements.  The first is 34 (in position 0), the second is 78 (in position 1), and the third is 45 (in position 2).

However, nums[3] returns nil in Ruby.  Why?  Because there’s no fourth element (and nothing in position 3).

Negative index numbers are also a thing!

arrays_index_sample2
Accessing elements with negative index numbers

The very last element in nums is at nums[-1].

The second-to-last element in nums is at nums[-2].

Third from the end is nums[-3].

However, nums[-4] returns a value of nil.  That’s because we only have three elements stored in nums.

Create

You can create new arrays several different ways.  Here are some of the basic methods:

  • Using []
  • Array.new

arrays_create_example1
Creating an empty array with []
Using [] is the most basic way to create a new array.

If we leave [] empty, it creates an empty array.  We can also store elements inside [] when we create the array.

Here’s another way to create an array:

arrays_create_example2
Creating an empty array with Array.new

Using Array.new by itself will create a new, empty array.

Something cool:  You can fill your array with nifty things if you pass stuff into the parentheses!

For example, Array.new(3) creates an array with a length of 5.  (It stores nil in each index.)

What if we want to start our array with something other than nil?  Just pass a second value!

Here’s how:  Array.new(3, "Ada") creates an array with a length of 5.  It stores "Ada" in each index.

The final bit of code is an example of passing a block.

Array.new(5) makes a new array with a length of 5, which is assigned to mult2.  As a second parameter, we pass { |i| i * 2 }.

What’s going on?  Well, i gets the indexes of the array (in this case, 0 through 4).

Then, it takes that i and multiplies it by 2.  So we get…

  • 0 * 2 (returns 0)
  • 1 * 2 (returns 2)
  • 2 * 2 (returns 4)
  • 3 * 2 (returns 6)
  • 4 * 2 (returns 8)

The result?  A new array populated with five even numbers!

Printing an Array

If we puts an array, it’ll display each element on its own line.  (For smaller sets of data, that’s fine…but for larger sets, it’s a hassle.)

If we print an array, we’ll get a neat list with square brackets and commas.  (Pretty!)

arrays_printing
Printing an array with puts, print and string interpolation combined with puts

Lastly, we can also combine puts with string interpolation.  This gives us the same square-brackets-and-commas layout.  (Pretty!)

Change and Access

We can change and access an array with its indices.

For example, it’s possible to assign new values to a specific index number.

In this case, list[0] originally holds a value of 0.  However, 7 is assigned to list[0] — and replaces 0 as the value.

We can also replace list[1] and list[2] in the same way:

arrays_change_access
Changing and accessing an array

Afterward, we access these new values via their respective index numbers.

Add to End

There are two ways to add elements to the end of an array:

  • .push
  • shovel operator ( << )

Here are some examples:

arrays_push
Adding to the end of an array with .push

If we pass "banana" into .push, we can add that string onto the end of list.

Something cool about .push:  You can pass multiple values at once.  They’ll get pushed onto the end of the array in the same order.  (RAD!)

Now let’s take a look at shovel…

arrays_shovel1
Adding to the end of an array with shovel

The << operator can shovel a value to the end of an array.

BUT!  You’ll get an error if you try passing more than one value (unlike .push).

arrays_shovel2
Adding an array to the end of an array (also with shovel)

Be careful not to accidentally stick a new array onto the end of your existing array!

Iterating over an Array

Iterating is another way of saying “looking at each one of the elements and performing some sort of action with them”.

Two different ways to iterate over an array:

  • do ... end block (for multi-line blocks)
  • curly braces {}   (for single-line blocks)

Let’s look at a couple of examples:

arrays_iterate1
Iterating over an array with .each — both ways

The do ... end block and curly braces do the exact same thing here.

Style-wise, the curly braces are better.  The reason is because we’re using a single-line block.

They both print out 1, 2 and 5 (or each element currently inside nums).

Another example:

arrays_iterate2
Iterating over an array with .each_with_index — both ways

While .each gives us each element in a collection, .each_with_index actually gives us both the element and its index number.  Nifty!

This example prints out:

  • 0: 1
  • 1: 4
  • 2: 6

Style-wise, the curly braces are the better choice.  That’s because we’ve only got one line of code in our block.

Useful Array Methods

Here’s a list of handy-dandy methods for arrays:

  • arr.length —  Returns number of elements inside arr
  • arr.empty? —  Returns true if there aren’t any elements in arr (false, otherwise)
  • arr.first —  Returns the first element in arr
  • arr.last —  Returns the last element in arr
  • arr.take(n) —  Returns the first n elements in arr
  • arr.include?(element) —  Returns true if element is stored in arr (false, otherwise)

There are plenty of other methods too…but I probably use these the most!

Exercises

Apparently, JSL participants go over these in person.  But I figure I may as well do these too.

Exercise 1

Create an array which will store the square of each value between 2 and 5, inclusive.

arrays_exercise1
Exercise 1 code

Both examples do the same thing.  They create an array, and store the square of each value between 2 and 5, inclusive.

In the first case, we use a do...end block.  The range is set with (2..5), and .each is used on the collection.  We use the .push method to add the square of each value being passed through i.

In the second case, we use curly braces to pass a block through Array.new.  The 4 tells Ruby we want 4 elements inside of list.

Using i as the index number, the curly braces calculate the square of each number between 2 and 5.

It does this by adding 2 to i (which starts at 0)…twice.  Then, the block multiplies both sums together — and pushes the new value into the corresponding position of i.

For example, the first index is 0.  And (0 + 2) * (0 + 2) equals 4.  Therefore, my first element is the square of 2: that is, 4.

Exercise 2

Given an array that contains three people, Ada Lovelace, Annie Easley, and Margaret Hamilton (1) Add one new person of your choice, (2) Output Annie Easley using the array, (3) Replace Ada Lovelace with Megan Smith

arrays_exercise2
Exercise 2 code

First, the array people is defined with a list of three strings.

Next, I pushed “Frances Spence” into the array with shovel.

After that, we output Annie Easley by referencing its index number (1, in this case).

Lastly, we assign "Megan Smith" to people[0]…which was previously occupied by “Ada Lovelace".  In other words, Ada Lovelace is replaced by Megan Smith.

Array people now consists of four elements — “Megan Smith”, “Annie Easley”, “Margaret Hamilton”, and “Frances Spence”.

Exercise 3

On paper, create an array which stores the names of people that inspire you. Then write down two different ways you can access the second-to-last name in your array?

arrays_exercise3
Exercise 3 code

In this case, my people array consists of three names: “Rebecca Sugar”, "Robert Clary" and "Leslie Odom, Jr.".

The second-to-last name is Robert Clary.  We can access Robert Clary two ways:

  • people[-2] (second-to-last position)
  • people[1] (second position)

Exercise 4

On paper, create an array which stores the numbers 1 – 15. Then write down two different ways of accessing the middle number?

arrays_exercise4
Exercise 4 code

I create an array called num, and assign the result of Array.new(15) { |i| i + 1 } to it.

In this case, I’m telling Ruby:  “Hey, I want a new array with 15 elements”.  Inside the curly braces (where i equals the current index number), I add 2 to i.  This gives me a list of numbers 1 – 15.

In this case, I’m just gonna say the middle number is 8. (That’s what you get when you divide num.length by 2, anyway).

Two different ways of accessing 8:

  • num[-8]
  • num[7]

Exercise 5

On paper, write code that will create an array named powers_of_2, and stores the fist 10 powers of 2

arrays_exercise5
Exercise 5 code

I assign the result of Array.new(10) { |i| 2 ** (i + 1) } to the variable powers_of_2.

In this case, I pass 10 as a parameter into Array.new.  This tells Ruby:  “Hey, I want 10 elements in my new array”.

Next, I use curly braces to populate powers_of_2.  With i as the current index number, I give 2 to the power (i + 1) by using the ** operator.

For example:  With i as index 0, I give 2 to the power (0 + 1) …or just 1.  The result is 2, which becomes my first element.

After the code exectues, powers_of_2 consists of 10 integers: 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024

Summary

This lesson introduces nil and arrays.

In Ruby, a variable automatically returns nil when it doesn’t have a value stored inside it.

Arrays are a container of things.  They are ideal when managing data that would otherwise require too many variables to manage.

Array indices start at 0 and increase by 1.

Here’s what we can do with arrays:

  • Create them (with [] or Array.new)
  • Print them (with puts, print or puts "#{arr}")
  • Change and access them (by referencing an element’s index)
  • Add to the end (with .push or shovel)
  • Iterate over them (with a do ... end block or curly braces)

Cool things I learned in JSL Day 5

In no particular order:

  • We can pass up to two parameters into Array.new
  • We can also pass a block as a parameter with curly braces (to populate our new array with particular values)
  • Curly braces are a great way to execute a single line of code for .each
  • .each_with_index gives us both the element and its index

Leave a comment