Skip to content

Instantly share code, notes, and snippets.

@pragdave
Created September 8, 2010 17:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pragdave/570434 to your computer and use it in GitHub Desktop.
Save pragdave/570434 to your computer and use it in GitHub Desktop.
input = [ 1, 2, 3, 4, 5, 8, 9, 11, 12, 13, 15 ]
# Need to box the value to make it mutable
State = Struct.new(:last_value)
def returning(value) yield; value; end
# divide the input into runs of consecutive numbers
s = input.slice_before(State.new(input.first)) do |value, state|
returning(value != state.last_value.succ) do
state.last_value = value
end
end
# replace runs of 3 or more with first-last
p s.map {|runs| runs.size < 3 ? runs : "#{runs.first}-#{runs.last}"}
.flatten
.join(', ') # => 1-5, 8, 9, 11-13, 15
@lmarburger
Copy link

I love returning. I wish it was part of core Ruby along side tap. This is a prime example of how using returning instead of tap clearly expresses the intent.

@drewblas
Copy link

drewblas commented Sep 8, 2010

I totally agree. I don't think this is a good example of how to use slice_before. But it's a great example of how to use returning

@zeedunk
Copy link

zeedunk commented Sep 15, 2010

Thanks for posting this, I made use of this example in a refactoring of the scoring koan that I posted here: http://gist.github.com/580960

Totally loving playing with ruby's Enumerable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment