Sandwich Scheduling: a look at Ruby's Array cycle method
- By Tim Ash
- 28 September
How Ruby can help you schedule your sandwiches
How Ruby can help you keep track of your lockdown exercise routine
Charlotte hasn’t been able to get to the gym recently, as she’s stuck at home due to the coronavirus lockdown. She’s having to get by with doing a lot of push-ups, and has been keeping a careful record of how many push-ups she manages to do each day. Each day’s total has been added to a Ruby array:
daily_push_up_totals = [10, 15, 25, 27, 30, 50, 55, 55, 60, 62, 62, 65, 65, 66]
Charlotte would like to know two things: the total number of push-ups she’s done each week, and her greatest improvement from one day to the next.
To calculate the total of number of push-up Charlotte has done each week, one approach would be to use each_slice
. This Array method divides the array into sections (or slices) and passes each section to the block. The number of values in each section is passed in as a parameter. So, for example:
daily_push_up_totals.each_slice(7) { |week_totals| print weekly_totals }
would result in:
[10, 15, 25, 27, 30, 50, 55][55, 60, 62, 62, 65, 65, 66]
We’ve managed to divide up the array into slices of seven values each, so all we need to do obtain the weekly totals is to add up each slice using sum
:
daily_push_up_totals.each_slice(7) { |week_totals| puts "Weekly total: #{week_totals.sum} }
resulting in:
Weekly total: 212
Weekly total: 445
We can make the output more useful by using with_index
:
daily_push_up_totals.each_slice(7).with_index(1) { |week_totals, week_number| puts "Total for week #{week_number}: #{week_totals.sum} }
which will give us:
Total for week 1: 212
Total for week 2: 445
So how can we figure out Charlotte’s greatest day-on-day improvement? Let’s try using each_cons
. This Array method supplies the given block with n
consecutive elements, starting from each element in turn. Confused? An example should make things clearer:
daily_push_up_totals.each_cons(2){ |values| print values }
will return:
[10, 15][15, 25][25, 27][27, 30]...
and so on.
Given this, calculating the greatest day-on-day improvement is a case of finding the differences between each of these pairs of daily totals, and finding the maximum:
daily_push_up_totals.each_cons(2).map{ |day1, day2| day2 - day1 }.max
returns:
20
We’re done - Charlotte will now be able to keep track of her progress no matter how long the lockdown lasts.
Thanks to Adam L. Watson for spotting an error in a previous version of this post.
I’d love to hear your thoughts on each_slice
, each_cons
, the uses you’ve found for them, and indeed, exercising during lockdown. Why not leave a comment below?
How Ruby can help you schedule your sandwiches
Another way Ruby can help you keep track of your lockdown exercise routine
How Ruby can help you mix the drinks and bust some moves at the charity ball
You won't believe what happens when all the animals run away from the zoo.
Home, home on the Range, where the Ewoks and the Wookies play
An example of Ruby metaprogramming, by way of juggling chainsaws.
We would love to hear from you so let's get in touch!