Hi,
I wanted to count consecutive elements in an array:
[1,1,1,2,2,2,2,3,4,4,4,4].count_streams #=> [3,4,1,4]
module Enumerable
def count_streams
last_seen = nil
self.inject([]) { |a, elem|
if last_seen == elem then a[-1] += 1 else a << 1 end
last_seen = elem
a
}
end
end
However, the assignment to "last" outside of the block seems ugly, so
I changed inject to take additional parameters:
module Enumerable
# works just like regular inject, but passes the additional parameters
# to the block
def inject_with_state(memo, *other)
self.each { |obj|
memo, *other = yield(memo, obj, *other)
}
memo
end
def count_streams
self.inject_with_state([], nil) { |a, elem, last_seen|
if last_seen == elem then a[-1] += 1 else a << 1 end
[a, elem]
}
end
end
Is this a good solution to the problem?
I think that inject_with_state could be made fully backwards
compatible to inject, it would be nice if inject could be changed to
support this. What do you think?
Viele Grüße,
Levin