You must be thinking, "did not we learn about array already?" We did. However, Array is a big class as it has more than 100 public methods. In this lesson we are going to learn some of them, especially the ones you will need but not already covered before.
You can take a look at the whole API here.
To break down elements of an array, we can use:
a, b = [1, 2]
It also works with multidimensional array.
a, b = [[1, 2], [3, 4, 5]]
It can even work when used inside of a block
[[1, 2], [3, 4, 5]].each { |a, b| puts "#{a} #{b}" }
Can you guess the result of these assignments?
a, b = [1, 2, 3]
c, d = [[1, 2], [3, 4, 5], [6, 7]]
e, f, g = [4, 5]
Can you complete this method?
compute([[1, 2], [3, 4]])
# returns [3, 7]
a, b = [1, 2, 3]
# the value of a is 1
# the value of b is 2
c, d = [[1, 2], [3, 4, 5], [6, 7]]
# the value of c is [1, 2]
# the value of d is [3, 4, 5]
e, f, g = [4, 5]
# the value of e is 4
# the value of f is 5
# the value of g is nil
def compute(array)
array.map { |(a, b)| a + b }
end
We have learned about this before, let's review it again:
head, *tail = [1, 2, 3, 4]
# what is the value of head?
# what is the value of tail?
*head, tail = [5, 6, 7, 8]
# what is the value of head?
# what is the value of tail?
head, *middle, tail = [5, 6, 7, 8]
# what is the value of head?
# what is the value of middle?
# what is the value of tail?
head, *tail = [1, 2, 3, 4]
# the value of head is 1
# the value of tail is [2, 3, 4]
*head, tail = [5, 6, 7, 8]
# the value of head is [5, 6, 7]
# the value of tail is 8
head, *middle, tail = [5, 6, 7, 8]
# the value of head is 5
# the value of middle is [6, 7]
# the value of tail is 8
Complete this method:
median(1, 3, 2)
# return the median value of 1, 2, 3 that is 2
median(1, 3, 2, 4)
# return the median value of 1, 2, 3, 4 that is (2 + 3)/2 = 2.5
Complete this method:
def median(*list)
mid = list.size/2
sorted = list.sort
if sorted.length.odd?
sorted[mid]
else
(sorted[mid-1] + sorted[mid]).to_f / 2
end
end
Guess what these operations will return:
a = *(1..10)
# what is the value of a?
b = *"Iqbal"
# what is the value of b?
def compute(a, b)
a + b
end
# pass [1, 2] to method compute
[[1, 2, 3, 4], [42, 43]].each { |a, *b| puts "#{a} #{b}" }
# what will be printed by the expression above?
a = *(1..10)
# the value of a is [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = *"Iqbal"
# the value of b is ["Iqbal"]
def compute(a, b)
a + b
end
compute(*[1, 2])
[[1, 2, 3, 4], [42, 43]].each { |a, *b| puts "#{a} #{b}" }
# it will print:
# 1 [2, 3, 4]
# 42 [43]
What is the result of these expressions?
[4, 8, 15, 16, 23, 42].count
# what will this return?
[42, 8, 15, 16, 23, 42].count(42)
# what will this return?
["Jacob", "Alexandra", "Mikhail", "Karl", "Dogen", "Jacob"].count("Jacob")
# what will this return?
[4, 8, 15, 16, 23, 42].count { |e| e % 2 == 0 }
# what will this return?
[4, 8, 15, 16, 23, 42].count
# 6
[42, 8, 15, 16, 23, 42].count(42)
# 2
["Jacob", "Alexandra", "Mikhail", "Karl", "Dogen", "Jacob"].count("Jacob")
# 2
[4, 8, 15, 16, 23, 42].count { |e| e % 2 == 0 }
# 4
What is the result of these expressions?
[4, 8, 15, 16, 23, 42].index(15)
# what is the return value of expression above?
[4, 8, 15, 16, 23, 42].index { |e| e % 2 == 0 }
# what is the return value of expression above?
[4, 8, 15, 16, 23, 42].index(15)
# 2
[4, 8, 15, 16, 23, 42].index { |e| e % 2 == 0 }
# 0
What is the result of these expressions?
[4, 8, 15, 16, 23, 42].flatten
# what is the return value of expression above?
[4, [8], [15], [16, [23, 42]]].flatten
# what is the return value of expression above?
[4, [8], [15], [16, [23, 42]]].flatten(1)
# what is the return value of expression above?
[4, 8, 15, 16, 23, 42].flatten
# [4, 8, 15, 16, 23, 42]
[4, [8], [15], [16, [23, 42]]].flatten
# [4, 8, 15, 16, 23, 42]
[4, [8], [15], [16, [23, 42]]].flatten(1)
# [4, 8, 15, 16, [23, 42]]
What is the result of these expressions?
[nil, 4, nil, 8, 15, 16, nil, 23, 42, nil].compact
[nil, 4, nil, 8, 15, 16, nil, 23, 42, nil].compact
# [4, 8, 15, 16, 23, 42]
What is the result of these expressions?
a = [4, 8, 15, 16, 23, 42]
b = a.shift
# what is the value of a?
# what is the value of b?
c = [4, 8, 15, 16, 23, 42]
d = a.shift(2)
# what is the value of c?
# what is the value of d?
e = [8, 15, 16, 23, 42].unshift(4)
f = [16, 23, 42].unshift(4, 8, 15)
# what is the value of e?
# what is the value of f?
a = [4, 8, 15, 16, 23, 42]
b = a.shift
# the value of a is [8, 15, 16, 23, 42]
# the value of b is 4
c = [4, 8, 15, 16, 23, 42]
d = c.shift(2)
# the value of c is [15, 16, 23, 42]
# the value of d is [4, 8]
e = [8, 15, 16, 23, 42].unshift(4)
f = [16, 23, 42].unshift(4, 8, 15)
# the value of e is [4, 8, 15, 16, 23, 42]
# the value of f is [4, 8, 15, 16, 23, 42]
Stack is an abstract data type with a bounded (predefined) capacity. Stack allows adding and removing elements in particular order. Every time an element is added, it goes on the top of the stack. The only element that can be removed from a stack is the element at the top of it.
Here are some basic features of a Stack:
More Stack features:
Queue is an abstract data type, sometimes implemented with a bounded (predefined) capacity, sometimes not. Queue allows adding and removing elements in particular order. Every time an element is added, it goes to the back part of the queue called "tail" (or sometimes "rear"). The only element that can be removed from a queue is the element at the front part of the queue called "head" (or sometimes just "front").
Here are some basic features of a Queue:
More Queue features:
This is how adding and removing element visualized:
Adding Element
Removing Element
require_relative '../stack.rb'
describe "Stack" do
before :each do
@s = Stack.new(4)
end
it "should be able to be initialized with a size" do
expect(@s.class.name).to eq("Stack")
end
it "should have size" do
expect(@s.size).to eq(4)
end
it "should have elements" do
expect(@s.elements).to eq([])
end
it "should show the size and the elements of the Stack when printed" do
expect(@s.to_s).to eq("size: 4, elements: []")
end
describe "push" do
context "with normal state" do
it "should be able to add new element with push method" do
@s.push(1)
expect(@s.to_s).to eq("size: 4, elements: [1]")
end
end
context "with overflow state" do
it "should not be able to add new element with push method" do
@s.push(1)
@s.push(2)
@s.push(3)
@s.push(4)
expect(@s.push(5)).to eq("stack overflow, can't add new element")
end
end
end
describe "pop" do
context "with normal state" do
it "should be able to remove an element with pop method" do
@s.push(1)
@s.push(2)
@s.push(3)
@s.push(4)
expect(@s.pop).to eq(4)
end
it "should be able to remove an element with pop method" do
@s.push(1)
@s.push(2)
@s.push(3)
@s.push(4)
@s.pop
expect(@s.to_s).to eq("size: 4, elements: [1, 2, 3]")
end
end
context "with underflow state" do
it "should not be able to remove any element with pop method" do
expect(@s.pop).to eq("stack underflow, can't remove any element")
end
end
end
describe "look" do
it "shold be able to look up the top element" do
@s.push(1)
@s.push(2)
@s.push(3)
@s.push(4)
expect(@s.look).to eq(4)
end
it "shold be able to look up the top element without removing it from the stack" do
@s.push(1)
@s.push(2)
@s.push(3)
@s.push(4)
@s.look
expect(@s.to_s).to eq("size: 4, elements: [1, 2, 3, 4]")
end
end
end
Based on this spec, create your own Stack
Create your own spec & implementation of Queue data type.