Ruby Arrays
Tags: ruby, tutorial
Published: 2020-06-18 17:17:49

This week we'll be diving deeper into Arrays in Ruby. We touched a bit on them in a previous lesson about Ruby classes, and this time we'll cover them more in depth and demonstrate why they are such a useful programming tool.

<h1>Array Recap</h1>
An array is a collection of data stored in list form for your program to access. It is denoted with opening and closing brackets (`[]`). A couple of examples of arrays are as follows:

```ruby
numbers_array = [1, 2, 3, 4, 5]
#This is an array of 5 different Integers.

words_array = ["words", "to", "fill", "this", "array"]
#This is an array of 5 different Strings.

single_array = ["this, looks, like, a, lot, of, different, words, but, a, syntax, error, makes, this, a, one, string, array"]
#This is an array with only 1 String.
```
You can also declare an empty array in 2 different ways, one like above and the other via the class constructor:
```ruby
my_array = []
#=> []
#Nice and simple

my_array = Array.new
#=> []
#Same result and a bit more typing.
```
And that's it, no tricky syntax or creation method. You create an array in the exact same way you would create a varaible in Ruby. As a matter of fact, when declaring an array, think of it as a short cut for declaring multiple variables at one time. An array is a very convenient storage container for a programmer to help keep their program clean and organized. 

Array's are indexed starting with the number 0. This means the first element in each array will be called with the syntax `array_name[0]`, the second element `array_name[1]`, and so forth. Keep this little detail in mind as you build programs, or your neat little organizational tool will become a serious headache very quickly.

```ruby
numbers_array = [1, 2, 3, 4, 5]
#An array of 5 elements.

puts numbers_array[0]
#=> 1

puts numbers_array[2]
#=> 3

puts numbers_array[5]
#=> nil
```
One more thing about array indexes. While 0->1->2->etc will move forward from the first element in an array, you can also start from the very end of an array using negative numbers. When doing this the number `-1` will always be assigned as the last element in an array, `-2` the second to last element, and the first element will have the same negative number as the length of the array.

```ruby
numbers_array = [1, 2, 3, 4, 5]
#An array of 5 elements.

puts numbers_array[0]
#=> 1

puts numbers_array[-1]
#=> 5

puts numbers_array[-3]
#=> 3
puts numbers_array[-5]
#=> 0 (in our previous example an index of positive 5 returned nil)
```

**Remember negative indexes start at -1 and not zero**. 

<h1>Array Methods</h1>
So we can see the value and ease of use of an array vs declaring all those separate variables. But what if you wanted to add or subtract another element to the array? You *could* just add or subtract from the array directly for permanent global changes, but what if you only wanted to add or remove an element is more specific cases? What if you want to know how many elements are in an array? Do you want to count each one by hand? No, you do not. Luckily Ruby comes ready to rock with many helpful methods specifically catered to arrays!

You can view all the possible methods usable on an array with the `methods` method as such:

```
C:\Users\Brandon>irb
irb(main):001:0> my_array = [1, 2, 3, 4]
=> [1, 2, 3, 4]
irb(main):002:0> my_array.methods
=> [:to_h, :include?, :at, :fetch, :last, :union, :difference, :push, :append, :pop, :shift, :unshift, :each_index, :join, :rotate, :rotate!, :sort!, :sort_by!, :collect!, :map!, :select!, :filter!, :keep_if, :values_at, :delete_at, :delete_if, :reject!, :transpose, :fill, :assoc, :rassoc, :uniq!, :compact, :*, :+, :flatten!, :&, :shuffle, :sample, :compact!, :flatten, :combination, :shuffle!, :-, :repeated_permutation, :sort, :product, :bsearch, :repeated_combination, :count, :find_index, :select, :filter, :reject, :collect, :map, :permutation, :first, :all?, :bsearch_index, :any?, :none?, :one?, :reverse_each, :zip, :take, :take_while, :drop, :drop_while, :cycle, :sum, :uniq, :|, :insert, :<=>, :<<, :index, :rindex, :replace, :==, :clear, :pack, :[], :[]=, :empty?, :eql?, :max, :min, :reverse, :inspect, :concat, :prepend, :reverse!, :length, :size, :each, :to_ary, :delete, :to_a, :to_s, :slice, :slice!, :dig, :hash, :to_set, :find, :entries, :sort_by, :grep, :grep_v, :detect, :find_all, :flat_map, :collect_concat, :inject, :reduce, :partition, :group_by, :minmax, :min_by, :max_by, :minmax_by, :member?, :each_with_index, :each_entry, :each_slice, :each_cons, :each_with_object, :chunk, :slice_before, :slice_after, :slice_when, :chunk_while, :lazy, :chain, :instance_variable_defined?, :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :tap, :methods, :singleton_methods, :protected_methods, :instance_variables, :instance_variable_get, :instance_variable_set, :private_methods, :public_methods, :method, :singleton_method, :public_send, :public_method, :define_singleton_method, :extend, :to_enum, :enum_for, :===, :=~, :!~, :respond_to?, :freeze, :object_id, :send, :display, :nil?, :class, :singleton_class, :clone, :dup, :itself, :yield_self, :then, :taint, :tainted?, :untaint, :trust, :frozen?, :untrust, :untrusted?, :equal?, :!, :__id__, :instance_exec, :!=, :instance_eval, :__send__]
irb(main):003:0>
```

That's a ton of methods! Granted not all are `array` specific, but we'll sort out some of the most popular and need to know ones here. 

<h3>Basic Array Methods</h3>
These are some of the methods to gather information about your array. 

`inspect` - This method returns a ***string*** version of the array containing all the current elements inside of it.

```
C:\Users\Brandon>irb
irb(main):001:0> my_array = [1, 2, 3, 4]
=> [1, 2, 3, 4]
irb(main):002:0> my_array.inspect
=> "[1, 2, 3, 4]"
irb(main):003:0>
```

`length` - This method returns the number of elements currently in an array. This method will be frequently used in a ***ton*** of programming math and troubleshooting, so it's best to familiarize yourself with it quickly.

```
C:\Users\Brandon>irb
irb(main):001:0> my_array = [1, 2, 3, 4]
=> [1, 2, 3, 4]
irb(main):002:0> my_array.inspect
=> "[1, 2, 3, 4]"
irb(main):003:0> my_array.length
=> 4
irb(main):004:0>
```
`index` - This method will return the *index number* of the first occurrence of its given argument.

```
C:\Users\Brandon>irb
irb(main):001:0> my_array = [1, 1, 2, 3, 4]
=> [1, 1, 2, 3, 4]
irb(main):002:0> my_array.index(1)
=> 0
irb(main):003:0>
```
Note we only get '0' as the index even though we have multiple '1's in the array. You probably won't be performing this very often, but can be useful in a pinch in larger arrays to quickly identify an index number when needed.

`first` & `last` - These methods will return the value of the first or last element in an array.

```
C:\Users\Brandon>irb
irb(main):001:0> my_array = [1, 2, 3, 4]
=> [1, 2, 3, 4]
irb(main):002:0> my_array.first
=> 1
irb(main):003:0> my_array.last
=> 4
irb(main):004:0>
```

`sort` - A method that will sort your array. By default, it will sort in ascending order (lowest to highest). 

```ruby
my_array = [3, 1, 4, 2]

print my_array.sort
#=> [1, 2, 3, 4]
#We used print to see the return in array form.
```

`reverse` - As the name implies, this will reverse your array.

```ruby
my_array = [1, 2, 3, 4]

print my_array.reverse
#=> [4, 3, 2, 1]
```

<h3>Adding and Removing Elements</h3>
Arrays come with several methods to quickly manipulate the number of elements in them. 

`<<` **(AKA The Shovel Operator)** - The shovel operator will add an element to the *end* of an existing array very painlessly. It is the preferred method to add items to an array due to it's simplicity, though there are other methods you must use if you need something injected elsewhere into an array.

```
C:\Users\Brandon>irb
irb(main):001:0> my_array = [1, 2, 3, 4]
=> [1, 2, 3, 4]
irb(main):002:0> my_array << 5
=> [1, 2, 3, 4, 5]
irb(main):003:0>
```

`push` - This method is the longer equivalent of the `<<` operator. It add's a new item to the *end* of the array.

```
C:\Users\Brandon>irb
irb(main):001:0> my_array = [1, 2, 3, 4]
=> [1, 2, 3, 4]
irb(main):002:0> my_array.push(5)
=> [1, 2, 3, 4, 5]
irb(main):003:0>
```
`unshift` - This method will add an element to the *front* of an array. Not as common as `<<` or `push` but more often than not you will be manipulating either the first or last element in an array so it's good to keep this one in mind.

```
C:\Users\Brandon>irb
irb(main):001:0> my_array = [1, 2, 3, 4]
=> [1, 2, 3, 4]
irb(main):002:0> my_array.unshift(0)
=> [0, 1, 2, 3, 4]
irb(main):003:0>
```

`pop` - This method will remove the *last* element from an array and return it.

```
C:\Users\Brandon>irb
irb(main):001:0> my_array = [1, 2, 3, 4]
=> [1, 2, 3, 4]
irb(main):002:0> my_array.pop
=> 3
irb(main):003:0>
```
`shift` - This method will remove the *first* element in an array and returns it. 

```
C:\Users\Brandon>irb
irb(main):001:0> my_array = [1, 2, 3, 4]
=> [1, 2, 3, 4]
irb(main):002:0> my_array.shift
=> 1
irb(main):003:0>
```

**Note:** With `unshift` & `push` you have to pass the value of the element you wish to add as an argument, but since `pop` & `shift` are removing already known elements no argument is necessary. 

`delete_at`- This method will remove an element at a specific index. Rarely used, but it's good to know if you ever find yourself needing to add an element into the middle of an array for whatever reason.

```
C:\Users\Brandon>irb
irb(main):001:0> my_array = [1, 2, 3, 4]
=> [1, 2, 3, 4]
irb(main):002:0> my_array.delete_at(2)
=> 3
irb(main):003:0>my_array
=> [1, 2, 4]
irb(main):004:0>
```

`insert` - This method adds an element to an array at a specific index. It takes 2+ arguments, the first is the index you want to start the insert at, and the second (and possibly more arguments) are the elements you want to add. 

```
C:\Users\Brandon>irb
irb(main):001:0> my_array = ["All", "Lives", "matter", "yours", "too!"]
=> ["All", "Lives", "matter", "yours", "too!"] 
```

In this array we a very true an encouraging sentiment, but it doesn't quite capture our feelings. We can start by removing the "yours" element with `delete_at`.
**Note, arrays are not great sentence constructors!**

```
irb(main):002:0> my_array.delete_at(3)
=> "yours"
#=> ["All", "Lives", "matter", "too!"]
```

Now let's add a few more words with `insert`.

```
irb(main):003:0> my_array.insert(2, "can't")
=> ["All", "Lives", "can't", "matter", "too!"]
```
We've definitely changed the sentiment here, and not for the better. Let's fix it with another `insert`.

```
irb(main):004:0> my_array.insert(4, "until", "Black", "Lives", "Matter")
=> ["All", "Lives", "can't", "matter", "until", "Black", "Lives", "Matter", "too!"]
```

Perfect!

<h1>Conclusion</h1>
This is a very long blog post, and with good reason! Arrays are a major part of programming, and there is a ton of ground to cover. Quite simply there is absolutely no way out of a ton of reading and research on this subject. A good example will be next week when we cover part two, array iteration where we introduce even *more* array methods! 

<h1>Ruby Arrays Lab</h1>
You guessed it, another lab! Let's drive these lesson home with a little practice. Complete the [Ruby Array Methods Lab](https://github.com/BMWeygant/Ruby-Array-Methods-Lab).