The each_cons
method in Ruby on Rails is a versatile tool that simplifies iterating over consecutive pairs in a collection. With just a single line of code, we can perform tasks such as finding patterns or calculating differences between adjacent elements. In this blog post, we’ll explore the various use cases of each_cons
, starting from simple examples and gradually progressing to more complex ones.
Simple Example: let’s start with a basic example using an array of numbers. Here, each_cons(2)
iterates over consecutive pairs within the numbers
array. The variable pair
receives an array containing two adjacent elements on each iteration.
1
2
3
4
5
6
7
8
9
10
11
numbers = [1, 2, 3, 4, 5]
numbers.each_cons(2) do |pair|
puts "Pair: #{pair}"
# Additional logic to manipulate the pair
end
#=> Pair: [1, 2]
#=> Pair: [2, 3]
#=> Pair: [3, 4]
#=> Pair: [4, 5]
Finding Patterns: each_cons
is handy for identifying patterns in a sequence. Here, each_cons(3)
iterates over consecutive triples of characters in the text
string.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
text = "Hello, world!"
text.chars.each_cons(3) do |triple|
puts "Triple: #{triple.join}"
# Additional logic to analyze the triple
end
#=> Triple: Hel
#=> Triple: ell
#=> Triple: llo
#=> Triple: lo,
#=> Triple: o,
#=> Triple: , w
#=> Triple: wo
#=> Triple: wor
#=> Triple: orl
#=> Triple: rld
#=> Triple: ld!
In this example, we use each_cons(2)
to iterate over consecutive pairs of words in the words array. The max_by
method is used to find the pair with the maximum difference in length. In this case, the longest consecutive sequence is between elephant
and frog
.
1
2
3
4
5
6
7
words = ["apple", "banana", "cat", "dog", "elephant", "frog", "giraffe"]
longest_sequence = words.each_cons(2).max_by { |w1, w2| w2.length - w1.length }
puts "Longest consecutive sequence: #{longest_sequence}"
#=> Longest consecutive sequence: ["elephant", "frog"]
Calculating Prices Differences: each_cons
is also useful for calculating differences between adjacent elements. In this example, each_cons(2)
is combined with map
to calculate the differences between consecutive elements in the prices
array.
1
2
3
4
5
6
7
prices = [10.5, 12.3, 11.8, 14.2, 13.5]
differences = prices.each_cons(2).map { |pair| pair[1] - pair[0] }
puts "Price differences: #{differences}"
#=> Price differences: [1.8, -0.5, 2.4, -0.7]
Adding Numbers: In this example, we use each_cons(2)
to iterate over consecutive pairs of numbers in the numbers
array. The map
method calculates the sum of each pair, resulting in the array [4, 8, 12, 16]
.
1
2
3
4
5
6
7
numbers = [1, 3, 5, 7, 9]
sums = numbers.each_cons(2).map { |n1, n2| n1 + n2 }
puts "Pair sums: #{sums}"
#=> Pair sums: [4, 8, 12, 16]
Advanced Analysis: each_cons
can handle more complex scenarios, such as analyzing sequences of objects. Considering an array of hashes, each_cons(3)
iterates over consecutive triples of hashes in the data
array. We calculate the average value of each triple based on the value
attribute and print it to the console.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data = [
{ id: 1, value: 10 },
{ id: 2, value: 15 },
{ id: 3, value: 12 },
{ id: 4, value: 20 }
]
data.each_cons(3) do |triple|
average = triple.sum { |hash| hash[:value] } / triple.size.to_f
puts "Triple average: #{average}"
end
#=> Triple average: 12.333333333333334
#=> Triple average: 15.666666666666666
#=> Triple average: 15.666666666666666
Stock Market Analysis: suppose you have an array of stock prices representing the closing prices of a stock over several days. You can use each_cons
to calculate the percentage change between consecutive closing prices, allowing you to analyze the volatility of the stock.
1
2
3
4
5
6
7
prices = [100.5, 102.3, 98.7, 105.2, 99.8, 101.4, 98.2]
percentage_changes = prices.each_cons(2).map { |p1, p2| ((p2 - p1) / p1) * 100 }
puts "Percentage changes: #{percentage_changes}"
#=> Percentage changes: [1.791044776119407, -3.5114503816793835, 6.595744680851055, -5.13245033112583, 1.603206412825632, -3.1653439153439157]
Fitness Tracker: imagine you have an array of daily step counts representing a person’s activity levels. You can use each_cons
to identify streaks of consecutive days where the person achieved a certain step count goal, helping track their consistency.
1
2
3
4
5
6
7
step_counts = [5000, 6000, 7500, 8000, 4000, 9000, 9500, 10000, 11000]
goal_streaks = step_counts.each_cons(3).select { |counts| counts.all? { |count| count >= 8000 } }
puts "Goal streaks: #{goal_streaks}"
#=> Goal streaks: [[8000, 9000, 9500], [9000, 9500, 10000], [9500, 10000, 11000]]
Time Series Analysis: suppose you have an array of temperature measurements taken at regular intervals throughout the day. You can use each_cons
to identify patterns or anomalies by comparing consecutive temperature values.
1
2
3
4
5
6
7
temperatures = [25.2, 25.5, 25.8, 26.1, 25.9, 26.3, 26.0, 25.7]
anomalies = temperatures.each_cons(4).select { |temps| temps.max - temps.min > 0.5 }
puts "Temperature anomalies: #{anomalies}"
#=> Temperature anomalies: [[25.2, 25.5, 25.8, 26.1], [25.9, 26.3, 26.0, 25.7]]