# Hi, I'm Nicholas Johnson!

software engineer / trainer / AI enthusiast

# Arrays

Like most languages Ruby allows you to create Arrays to hold multiple values. Arrays in Ruby are one dimensional, though you can declare an array of arrays if you feel the need.

## Creating Arrays

Create an array using square brackets like so:

``  cakes = ["florentine", "lemon drizzle", "jaffa"]``

Access an array using square brackets:

``````  cakes
=> "florentine"``````

## Zero Indexed

Arrays are zero indexed, so 0 is the first element.

## Polymorphic

As you might expect from Ruby, arrays can hold any type of element. This is allowed:

``  ["hello", 1, 0.5, false]``

## Manipulating arrays

Arrays can be manipulated in a huge variety of ways For example:

``````  [1,2,3] + [4,5,6]
=> [1, 2, 3, 4, 5, 6]``````

### Subtracting

``````  [1,2,3] - [1,3]
=> ``````

### Appending

``````  [1,2,3] << 4
=> [1, 2, 3, 4]``````

### Multiplication

``````  [1,2,3] * 2
=> [1, 2, 3, 1, 2, 3]``````

## Handy dandy array API

There are also a raft of array methods we can use, such as:

``````  [1,2,3].reverse
=> [3, 2, 1]

[1,2,3].include? 2
=> true``````

You might notice here that this method name has a question mark in it? This is a Ruby convention. Methods with a question mark return true or false.

``````  [4,9,1].sort
=> [1, 4, 9]``````

## Array splitting

Parallel assignment works when pulling values out of a array.

``````  array_of_numbers = [1,2,3,4]
a,b = array_of_numbers
a
=> 1
b
=> 2``````

We can also pull the first element, and return the rest of the array should we wish to:

``````  arr = [1,2,3]
a,*arr = arr
a
=> 1
arr
=> [2, 3]``````

This is a clever trick to know as it impresses people and make you look brainy.

## Creating an array using the to_a method

The to_a method allows many objects to be converted to arrays. For example an array can be created from a range as follows

``````  (1..10).to_a
=> [1,2,3,4,5,6,7,8,9,10]``````

## Ranges

Ranges are useful objects that can be used to represent a sequence. Ranges are defined using the .. or … syntax. For example:

``  1..10``

represents the sequence of numbers between 1 and 10.

``  1...10``

represents a range that excludes the high value. In this case the numbers 1 to 9

### Ranges in Memory

Ranges are compact. Every value in the range is not held in memory, so for example the range:

``  1..100000000``

…takes up the same amount of memory as the range:

``  1..2``

### Conversion to arrays

Ranges can be converted to arrays using to_a like so

``````  (1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]``````

Note we need to put braces around the range here to disambiguate the dots.

### Character Arrays

We can also declare arrays of characters like this:

``  'a'..'f'``

### Testing if a range contains a value.

We can use the equality === operator to test if a range contains a value. For example:

``````  ('a'..'f') === 'e'
=> true

('a'..'f') === 'z'
=> false``````

## Exercise - Iterating over an array

We can pass a block to an array to be executed on each item in that array. For example:

``  ['fork','knife','spoon'].each {|table_item| puts table_item}``

Our code doesn’t need to know the internal details of the array, it just passes a block, and lets the array sort itself out.

1. here is an array of strings. Pass a block to Array.each printing them out one by one.
``  ['cats','hats','mats','caveats']``
1. The each_with_index method accepts a block with two parameters, the value, and the index. Use it to print out the strings in the array preceded by their index in the array like this:
``````  1. cats
2. hats
3. mats
4. caveats``````
1. Repeat the exercise above, but now only print out every string with an odd number index.

2. Investigate the remove method. Modify your code to only print out only strings which contain the letter ‘c’

3. Functions which return nothing are hard to test. Modify your code so that instead of putting to the screen it returns a string. Use RSpec to test it.

## Exercise - Join

Use the join method to join the array together with commas, you should get something like this:

``  Fluffy, Hammy, Petunia``

## Array manipulation

Reverse the order of the array, output something like this:

``  Petunia, Hammy, Fluffy``

## Append two arrays to each other

Create an array of dogs. append it to the first. using the plus operator, then output both arrays together, like this:

``````  Fluffy
Hammy
Petunia``````

## Exercise - Map

Use Map to capitalise each element in the array prior to output, like so:

``````  FLUFFY
HAMMY
PETUNIA``````

Now capitalise and reverse each element in the array.

``````  PETUNIA
HAMMY
FLUFFY``````

## Exercise - Sort and reverse

Use sort to sort the array alphabetically like so:

``````  BARKY
FLUFFY
GOMEZ
HAMMY
PETUNIA
WOOFY``````

And sort the array in reverse order:

``````  WOOFY
PETUNIA
HAMMY
GOMEZ
FLUFFY
BARKY``````

### Sorting an Array Using a Block

By default array.sort will sort any array of values using the <=> spaceship method of the value. This method as we have seen returns -1, 0 or 1 depending on whether the value is lower, equivalent or greater than another value. The String class implements the <=> method by comparing the two values alphabetically, so by default array.sort sorts an array of strings alphabetically like so:

``````  array = ["James", "Derek", "Stuart", "Thomas"]
puts array.sort
=> Derek
James
Stuart
Thomas``````

If we want to override this, there are two easy ways to do it. First we can override the spaceship operator (coming soon). Alternately, we can pass Array.sort a block which can be used instead. For example the following code sorts an array in order of the second letter:

``````  array = ["James", "Derek", "Stuart", "Thomas"]
puts array.sort {|a,b| a <=> b}
=> James
Derek
Thomas
Stuart``````

Nice and Simple.

## Exercise - Sort according to the length of the string.

You can get the length of the string using “string”.length.

``````  BARKY
WOOFY
HAMMY
GOMEZ
FLUFFY
PETUNIA``````

## Modifying each element of an array with map

Map is an insanely useful array function that lets you modify each element of an array using a block.

Say you have an array of strings:

``  ['kittens', 'puppies', 'hamsters']``

Lets say you want to convert this to an array of symbols, you could do something like

``  ['kittens', 'puppies', 'hamsters'].map {|i| i.to_sym}``

## Exercise - Random Alphanumeric with Map

Use the Array#map method to generate a random string. You can generate a random letter by making an array of acceptable characters like so:

``  n = (0..9).to_a + ('a'..'z').to_a + ('A'..'Z').to_a + %w(_ -)``

You can then pull a random one out like so:

``  n.sample``

Now use map to generate a 128 character random string.