Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any standard method similar to tap but returning the block result instead of self?

Tags:

ruby

Let's say I have an array of time lengths expressed in minutes:

minutes = [20, 30, 80]

I would like to sum the array contents and output the result in <hours>:<minutes> format. For the example above I expect the result to be 02:10.

Is there any standard Ruby method (i.e. included in core or std-lib) allowing to do this in an one line method chain? (i.e. without using a variable to store an intermediate result). I mean something like:

puts minutes.reduce(:+).foomethod { |e| sprintf('%02d:%02d', e / 60, e % 60) }

What should foomethod be? Object.tap is quite close to what I need, but unfortunately it returns self instead of the block result.

like image 316
Marco Casprini Avatar asked Nov 13 '16 23:11

Marco Casprini


2 Answers

Try this one

puts sprintf('%02d:%02d', *minutes.reduce(:+).divmod(60))
like image 107
Ursus Avatar answered Oct 19 '22 03:10

Ursus


proc { |e| sprintf('%02d:%02d', e / 60, e % 60) }.call(minutes.reduce(:+)) #=>"01:00"

or if you prefer lambdas

->(e) { sprintf('%02d:%02d', e / 60, e % 60) }.call(minutes.reduce(:+)) #=>"01:00"

PS: If you want to make these even shorter, you can also use [] and .() for calling a lambda, i.e.

->(e) { sprintf('%02d:%02d', e / 60, e % 60) }.(minutes.reduce(:+)) #=>"01:00"
->(e) { sprintf('%02d:%02d', e / 60, e % 60) }[minutes.reduce(:+)] #=>"01:00"
like image 28
Rashmirathi Avatar answered Oct 19 '22 05:10

Rashmirathi