-
-
Save JEG2/570556 to your computer and use it in GitHub Desktop.
input = [ 1, 2, 3, 4, 5, 8, 9, 11, 12, 13, 15 ] | |
# divide the input into runs of consecutive numbers | |
last = input.first | |
s = input.slice_before(lambda { |i| [i != last + 1, (last = i)].first }) | |
# 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 |
For the sake of one-liners:
s = input.each_with_index.slice_before { |e,i| e != input[i-1]+1 }.map { |group| group.map { |e,l| e } }
I also thought adding some with_{prev,next} Enumerator:
class Enumerator
def with_next
return enum_for __method__ unless block_given?
loop { yield self.next, peek }
end
def with_prev
return enum_for __method__ unless block_given?
last = first
loop {
yield peek, last
last = self.next
}
end
end
Then it would be:
s = input.each.with_prev.slice_before { |e,l| e != l.succ }.map { |group| group.map { |e,l| e } }
What do you think ?
Isn't there quite a bit of overlap between with_next/prev and each_cons(2)?
Isn't there quite a bit of overlap between with_next/prev and each_cons(2)?
You are right about #with_next
, I made a mistake in the code
(I actually wanted to yield each element with the next one, including the last one, with itself or nil).
I indeed felt first to use #each_cons
, but the behavior is different:
#each_cons
will only yield (size-1)
times but #with_prev
will yield size
times.
This leads to the problem to know what is the "previous" of the first. I choose to have the first, as you do.
As we use #slice_before
, we need to yield each element, and say we want a new slice at the first
(with #each_cons
and considering it as (last,element), the first will be dropped).
[1,3,4,6,7,8].each_cons(2).slice_before { |l,e| e != l.succ }.map { |group| group.map { |l,e| e } }
# => [[3, 4], [6, 7, 8]]
I think we're all still feeling our way here. To me, it's like using #split, but having to manage more myself because the domain is more complex. I can live with that, but I'm expecting that over the next year or so we'll work out patterns that will help us