An Array is ordered, integer-indexed collections of any object.
arr = []
# or
arr = Array.new
To create an empty array, simply use:
arr = [1, 2, 3, 4, 5]
arr = ["a", "b", "c", "d", "e"]
We can also create an array with a set of values:
arr = %w(This is another way to make array of strings)
# result: ["This", "is", "another", "way", "to", "make", "array", "of", "strings"]
We can also create an array of strings like this:
arr = [1, "a", 2, "b", 3, "c"]
An array can contain different data types.
arr = [1, 2, 3, 4, 5]
arr << 6 # result: [1, 2, 3, 4, 5, 6]
To add an element to an array, we can use:
# Another way to create an array
arr = Array.new(3, 'abc') # ["abc", "abc", "abc"]
arr[0].upcase!
arr # ["ABC", "ABC", "ABC"]
arr[1] = 'xyz'
arr # ["ABC", "xyz", "ABC"]
# This time using block, we'll discuss about block later this week
arr = Array.new(3) { 'abc' } # ["abc", "abc", "abc"]
arr[0].upcase!
arr # ["ABC", "abc", "abc"]
arr[1] = 'xyz'
arr # ["ABC", "xyz", "abc"]
# This can be used to do many things, for instance: creating a multidimensional array
i = 1
Array.new(4) { Array.new(4) { i += 1 } }
# [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
# Guess what is the result of this expression:
[1, 2, 3, 4, 5][1]
[1, 2, 3, 4, 5].at[3]
To access an element in an array, we use its index.
# Guess what is the result of this expression:
[1, 2, 3, 4, 5][-2]
# Hint:
# With reverse index lookup,
# the last element of an array has an index value of -1
We can also use negative numbers as index. This is called reverse index lookup.
[1, 2, 3, 4, 5] # return 3
[1, 2, 3, 4, 5] # return 3 using reverse index lookup
# Without using index,
# Guess which methods to solve these:
[1, 2, 3, 4, 5].your_method_here # return the first element of this array
[1, 2, 3, 4, 5].your_method_here # return the last element of this array
[1, 2, 3, 4, 5][2] # return 3
[1, 2, 3, 4, 5][-3] # return 3 using reverse index lookup
# Without using index,
# Guess which methods to solve these:
[1, 2, 3, 4, 5].first # return the first element of this array
[1, 2, 3, 4, 5].last # return the last element of this array
arr = ["a", "b", "c", "d"]
arr[0, 1]
# result: ["a"]
# Can you guess the results of these expressions?
arr[0, 2]
arr[2, 2]
arr[2, 20]
arr[4, 0]
arr[4, 100]
arr[5, 0]
arr = ["a", "b", "c", "d"]
arr[0, 2]
# ["a", "b"]
arr[2, 2]
# ["c", "d"]
arr[2, 20]
# ["c", "d"]
arr[4, 0]
# []
arr[4, 100]
# []
arr[5, 0]
# nil
# Expression arr[4, 100] returns [], but arr[5, 0] returns nil. Why?
# -4 -3 -2 -1 << reverse index lookup
# 0 1 2 3 << normal index
# +---+---+---+---+
# | a | b | c | d |
# +---+---+---+---+
# 0 1 2 3 4 << numbering for two-argument indexing or start of range
# Try this:
(1..5)
(1..5).class
(1...5)
# What will this return?
[1, 2, 3, 4, 5] == (1..5)
[1, 2, 3, 4, 5] == (1..5).to_a
[1, 2, 3, 4, 5] == (1...5).to_a
In Ruby, there is a class called Range.
# Guess what is the result of this expression:
["a", "b", "c", "d"][0..2]
["a", "b", "c", "d"][0...2]
["a", "b", "c", "d"][2..-1]
We can slice an array using range.
a = [ 1, 3, 5, 7, 9 ]
a[1] = 'bat'
a[-3] = 'cat'
a[3] = [ 9, 8 ]
a[6] = 99
a = [ 1, 3, 5, 7, 9 ] #=> [1, 3, 5, 7, 9]
a[1] = 'bat' #=> [1, "bat", 5, 7, 9]
a[-3] = 'cat' #=> [1, "bat", "cat", 7, 9]
a[3] = [ 9, 8 ] #=> [1, "bat", "cat", [9, 8], 9]
a[6] = 99 #=> [1, "bat", "cat", [9, 8], 9, nil, 99]
a = [ 1, 3, 5, 7, 9 ]
a[2, 2] = 'cat'
a[2, 0] = 'dog'
a[1, 1] = [ 9, 8, 7 ]
a[0..3] = []
a[5..6] = 99, 98
a = [ 1, 3, 5, 7, 9 ] #=> [1, 3, 5, 7, 9]
a[2, 2] = 'cat' #=> [1, 3, "cat", 9]
a[2, 0] = 'dog' #=> [1, 3, "dog", "cat", 9]
a[1, 1] = [ 9, 8, 7 ] #=> [1, 9, 8, 7, "dog", "cat", 9]
a[0..3] = [] #=> ["dog", "cat", 9]
a[5..6] = 99, 98 #=> ["dog", "cat", 9, nil, nil, 99, 98]
[1, 2, 3, 4, 5].map { |i| i + 1 }
# Will generate a new array: [2, 3, 4, 5, 6]
We can transform the contents of an array according to a specified set of rules using the "map" method.
# Transform this array, multiple each element by 3
[1, 2, 3, 4, 5]
The curly braces and everything inside them is called a block. We'll come back to that later.
[1, 2, 3, 4, 5].collect { |i| i + 1 }
# Will generate a new array: [2, 3, 4, 5, 6]
We can also use the method "collect" which is an alias to the method "map". The two methods work interchangeably.
[1, 2, 3, 4, 5].collect { |i| i + 1 }
# Will generate a new array: [2, 3, 4, 5, 6]
We can also use the method "collect" which is an alias to the method "map". The two methods work interchangeably.
# Select only even numbers
[1,2,3,4,5,6].select { |number| number.even? }
# Select regions that has 6 or more characters
regions = ["Senen", "Menteng", "Gambir", "Cikini", "Pluit"]
regions.select { |region| region.size >= 6 }
We can filter elements of an array using the method "select".
# Guess which method to use
# 1. To delete element 4 from this array
arr = [1, 2, 3, 4, 5, 6]
arr.your_method_here
# 2. To delete the fourth element from this array
arr = [1, 2, 3, 4, 5, 6]
arr.your_method_here
# 3. To delete every even number from this array
arr = [1, 2, 3, 4, 5, 6]
arr.your_method_here
# 1. To delete element 4 from this array
arr = [1, 2, 3, 4, 5, 6]
arr.delete(4)
# 2. To delete the fourth element from this array
arr = [1, 2, 3, 4, 5, 6]
arr.delete_at(3)
# 3. To delete all odd numbers from this array
arr = [1, 2, 3, 4, 5, 6]
arr.delete_if { |number| number.odd? }
arr = ["Giovanni", "Iqbal", "Raymond", "Tara"]
for i in 0..3 do
puts "My name is #{arr[i]}"
end
We have learned about loop. To iterate elements in Ruby, we can use loop. In other programming languages, we may do something like this:
arr = ["Giovanni", "Iqbal", "Raymond", "Tara"]
for i in arr do
puts "My name is #{i}"
end
In Ruby, we can do it in better ways. For instance:
arr = ["Giovanni", "Iqbal", "Raymond", "Tara"]
arr.each do |name|
puts "My name is #{name}"
end
Even better, we can do it this way:
insert_dash(454793) # will return: '4547-9-3'
insert_dash(123456) # will return: '123456'
insert_dash(1003567) # will return: '1003-567'
insert_dash(24680) # will return: '24680'
insert_dash(13579) # will return: '1-3-5-7-9'
1. Insert Dash
Create a method called insert_dash. When given a number, this method will return a string containing the number with dash added between occurrences of two odd number consecutively.
high_and_low("4 5 29 54 4 0 -214 542 -64 1 -3 6 -6")
# return "542 -214"
high_and_low("1 -1") # return "1 -1"
high_and_low("1 1") # return "1 1"
high_and_low("-1 -1") # return "-1 -1"
high_and_low("1 -1 0") # return "1 -1"
high_and_low("1 1 0") # return "1 0"
high_and_low("-1 -1 0") # return "0 -1"
high_and_low("42") # return "42 42"
2. High and Low
Create a method called high_and_low. When given a string consisting a sequence of numbers, this method will return a string containing the highest and the lowest numbers in the sequence.
find_longest([1, 10, 100]) # return 100
find_longest([9000, 8, 800]) # return 9000
find_longest([8, 900, 500]) # return 900
find_longest([3, 40000, 100]) # 40000
find_longest([1, 200, 100000]) # return 100000)
3. Longest Digit
Create a method called find_longest. When given an array containing positive numbers, it will return the element with the longest digit. If there are two or more elements with the longest digit, it will return the first element with the longest digit.
a1 = ["arp", "live", "strong"]
a2 = ["lively", "alive", "harp", "sharp", "armstrong"]
in_array(a1, a2)
# will return: ["arp", "live", "strong"]
a1 = ["tarp", "mice", "bull"]
in_array(a1, a2)
# will return: []
4. In Array
Create a method called in_array. It receives two parameters "array1" and "array2". It will return an array containing unique elements of array1 that is a subset of elements in array2, arranged alphabetically.
deep_count([]) # will return 0
deep_count([1, 2, 3]) # will return 3
deep_count(["x", "y", ["z"]])
# will return 3 elements ("x", "y", ["z"]) in main array
# plus 1 element ("z") in sub array
# total = 4 elements
deep_count([1, 2, [3, 4, [5]]])
# total = 7 elements
deep_count([[[[[[[[[]]]]]]]]])
# total = 8 elements
5. Deep Count
Create a method called deep_count that will return the number of elements in an array, including the number of elements of its sub arrays.
def insert_dash(num)
i = 0
dashed_number = ""
num.to_s.chars.each do |char|
if char.to_i.odd? && dashed_number[i-1].to_i.odd?
i += 1
dashed_number += "-"
end
dashed_number += char
i += 1
end
dashed_number
end
1. Insert Dash - Basic Solution
def insert_dash(num)
num.to_s.gsub(/(?<=[13579])([13579])/, '-\1')
end
1. Insert Dash - Advanced Solution
def high_and_low(numbers)
arr = numbers.split(" ").map { |e| e.to_i }
"#{arr.max} #{arr.min}"
end
2. High and Low - Basic Solution
def high_and_low(numbers)
numbers.split(" ").map { |e| e.to_i }.minmax.reverse.join(' ')
end
2. High and Low - Advanced Solution
def find_longest(arr)
longest = nil
max_digit = 0
arr.each do |a|
if a.to_s.size > max_digit
max_digit = a.to_s.size
longest = a
end
end
longest
end
3. Longest Digit - Basic Solution
def find_longest(arr)
arr.max_by { |num| num.to_s.size }
end
3. Longest Digit - Advanced Solution
max_by() # public
# Returns the object in enum that gives the maximum value from the given block.
# If no block is given, an enumerator is returned instead.
# source: https://apidock.com/ruby/Enumerable/max_by
Reference
def in_array(array1, array2)
subset_array = []
array1.each do |a1|
array2.each do |a2|
subset_array << a1 if a2[a1] && !subset_array.include?(a1)
end
end
subset_array.sort
end
4. In Array - Basic Solution
def in_array(array1, array2)
array1.select{|s| array2.any?{|w| w.include?(s) } }.sort
end
4. In Array - Advanced Solution
def deep_count(a)
count = 0
if !a.empty?
a.each do |e|
count += 1
if e.is_a?(Array)
count += deep_count(e)
end
end
end
count
end
10. Deep Count - Basic Solution
def deep_count(a)
a.reduce(a.size) {
|size, element| size + (element.is_a?(Array) ? deep_count(element) : 0)
}
end
# reduce(p1 = v1, p2 = v2) public
# Combines all elements of enum by applying a binary operation,
# specified by a block or a symbol that names a method or operator.
# If you specify a block, then for each element in enum
# the block is passed an accumulator value (memo) and the element.
# If you specify a symbol instead, then each element in the collection
# will be passed to the named method of memo.
# In either case, the result becomes the new value for memo.
# At the end of the iteration,
# the final value of memo is the return value for the method.
# If you do not explicitly specify an initial value for memo,
# then uses the first element of collection is used as the initial value of memo.
# source: https://apidock.com/ruby/Enumerable/reduce
5. Deep Count - Advanced Solution