Exercising During Lockdown: a look at Ruby's Array each_cons and each_slice methods

How Ruby can help you keep track of your lockdown exercise routine

How Ruby can help you keep track of your lockdown exercise routine
Photo: Karl Solano

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



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?

Related Posts

Let's Work Together

We would love to hear from you so let's get in touch!