Certain Items From Array

We have an array of numbers and we want to get only the even numbers from that array:

array = [1, 2, 3,4, 5]
even_arr = []
array.each do |item|
  even_arr.push(item) if item.even?
end
puts even_arr

This code works but array has select to handle this in a better way.

select will only pick items for which the result of the given condition is true.

Let’s see it in action.

array = [1, 2, 3,4, 5]
even_arr = array.select do |item|
    item.even?
end

puts even_arr //[2, 4]

As we can see, the code is much cleaner compared to the previous one.

Array provides reject as a simpler way to reject certain items. reject will only reject items for which the result of condition is true. Let’s see it in action.

array = [1, 2, 3,4, 5]
even_arr = array.reject do |item|
    item.odd?
end

puts even_arr // [2, 4]

add an item to array using double arrows. use << to add to an array. Here are some examples:

numbers = [1,2,3]
numbers << 4
puts numbers // [1,2,3,4]

also can add another array to an array

numbers = [1,2, 3]
numbers << [4, 5]
puts numbers // [1,2,3,4,5]

Joining Arrays In the programming world, concatenation means adding two items. We can use + to concatenate two arrays.

numbers1 = [1,2,3,4]
numbers2 = [5,6]

all_numbers = numbers1 + numbers2
puts all_numbers // [1,2,3,4,5,6]

In this case, number1 and number2 did not change at all.

A new array was created by concatenating the two arrays.

Contrast this with push which changes the original array.

If an array has nil items and we want to remove these nil items, then we can use compact.

array1 = [1, 2, nill, 4, "6",  nil,  "John"]
array2 = array1.compact
puts array1 // [1, 2, nill, 4, "6",  nil,  "John"]
puts array2 //[1, 2, 4, "6",   "John"]

If an array has duplicate items, then we can use uniq to remove all the duplicates.

arr1 = [1, 2, 2, 3, 4, 4, 4, 5, 5, 6]
arr2 = arr1.uniq
puts arr1 // [1, 2, 2, 3, 4, 4, 4, 5, 5, 6]
puts arr2 // [1, 2, 3, 4, 5, 6]

We have an array which contains other arrays. We want to keep all the items of the arrays, but we want to remove all the arrays themselves.

Ruby provides flatten to do this job.

arr1 = [1, [2,3,4],5, [6,7]]
arr2 = arr1.flatten
puts arr1  // [1, [2,3,4],5, [6,7]]
puts arr2 // [1,2,3,4,5,6,7]

arr2 only has numbers and does not have any arrays. flatten does not change the original array. arr1 still contains the nested arrays.

uses the - sign to subtract or remove items from an array.

arr1 = [1,2,3,4,5]
arr2 = arr1 - [4,5]
puts arr1  [1,2,3,4,5]
puts arr2 // [1,2,3]

The - does not change the original array. A new array is created after removing the specific elements from the array.

Rather than taking four separate statements to assign values, the same thing can be done in one line as shown below:

array = [56, 78, "August 28"]
home_team_score, opposite_team_score, date_of_game = array

puts home_team_score // 56
puts opposite_team_score // 78
puts date_of_game // August 28

During destructuring, adding a star before a variable name makes that variable greedy and that variable takes up all the remaining values.

arr = [1,2,3]
a, *b = arr
puts a // 1
puts b // [2,3]

In the case given above, variable b takes up both the values 2 & 3 and puts them in an array.

arr = [1,2,3]
a ,*b, c = arr
puts a // 1 
puts b // [2]
puts c // 3

In the case provided above, even though b is greedy, Ruby first attempts to assign at least one value to each of the variables. In this case, one value is assigned to a, b & c. Since nothing else is left, b ends with only 2. But, since b is using a *, that 2 is an array.

Now, let’s try the same thing with more values.

arr = [1,2,3,4,5]
a, *b, c = arr
puts a // 1
puts b // [2,3,4]
puts c // 5

In this example, Ruby first assigned 1 to a and 2 to b and 5 to c. Still, we were left with 3 & 4 which got assigned to b.

Two Greedy Variables Will Cause Problems

arr = [1,2,3]

a, *b, *c = arr
//(file):3 unexpected token tSTAR
arr = [1,2,3]
a,b, c, d, e = arr
puts "a is #{a}"  // a is 1
puts "b is #{b}" // b is 2
puts "c is #{c}" // c is 3
puts "d is #{d}" // d is

If there are not enough values for variables, then the variables who did not get any value are assigned nil value by Ruby.

If a variable is using *, then it always get an array.

If there is no value for the greedy variable, then the final result is an empty array:

arr = [1,2,3]
a, b, c, *d = arr
puts a  // 1
puts b  // 2
puts c // 3
puts d // []

create an array using %w.

arr= %w(1 2 3)
puts arr // ["1", "2", "3"]

This version looks much cleaner. However, if there is a whitespace in the word, then we need to put a \ to escape the whitespace.

arr = %w(today tomorrow day\  after\ tomorrow )
puts arr  // ["today", "tomorrow", "day after tomorrow"]

use each_with_index then along with the value in the array, we also get the position of each value.

names = %w(wang da bo)
names.each_with_index do |name, index|
     puts "#{name} is at position #{index + 1}"
end

use sort to sort the elements in an array in the ascending order.

arr = [1,2, 66, 3, 88, 8]
sort_arr = arr.sort

puts sort_arr // [1,2,3,8, 66, 88]