What's the slickest, most Ruby-like way to do this?
[1, 3, 10, 5].diff
should produce
[2, 7, -5]
that is, an array of first order differences. I've come up with a solution which I'll add below, but it requires ruby 1.9 and isn't all that slick. what else is possible?
I like this functional style:
module Enumerable
def diff
each_cons(2).map {|pair| pair.reverse.reduce :-}
end
end
EDIT: I just realized that the reverse
is totally unnecessary. If this were a functional language, I would have used pattern matching, but Ruby doesn't support pattern matching. It does, however, support destructuring bind, which is a good enough approximation for pattern matching in this case.
each_cons(2).map {|first, second| second - first}
No smiley, though.
I like how this sounds if you just read it out loud from left to right: "For each pair, apply the difference between the first and second elements of the pair." In fact, I normally don't like the name collect
and prefer map
instead, but in this case that reads even better:
each_cons(2).collect {|first, second| second - first}
"For each pair, collect the difference between its elements." Sounds almost like a definition of first order difference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With