Lets say, we have an Array
of Strings
named words
and I want to instantiate a special Enumerator using eunum_for
on it which only counts Strings with the length != 3. Here is my proposal:
def words.n_each
select{|x| x.length != 3}.each do |y|
yield y
end
end
e4 = words.enum_for(:n_each)
e4.each do |w|
puts w
end
But there has to be a more smarter rubyish way to include the mechanics of the n_each
method in enum_for
- maybe inside a codeblock at the time of instantiation of the Enumerator. But how?
CodePudding user response:
Is lazy
what you are looking for?
p e4 = ["aaa","c","foo","aaaa"].lazy.reject{|s| s.size == 3 } # => <Enumerator::Lazy: ["aaa", "c", "foo", "aaaa"]>:reject>
e4.each do |w|
puts w
end
prints
c
aaaa
CodePudding user response:
class Array
def each_except_size_3
Enumerator.new do |y|
(0..size-1).each do |i|
s = self[i]
y << s unless s.size == 3
end
end
end
end
enum = ['guppy', 'owl', 'ox', 'cow', 'bear', 'lion'].each_except_size_3
#=> #<Enumerator: #<Enumerator::Generator:0x00007fc1a41b9a28>:each>
enum.to_a
#=> ["guppy", "ox", "bear", "lion"]
enum.take(4)
#=> ["guppy", "ox", "bear", "lion"]
enum.take(3)
#=> ["guppy", "ox", "bear"]
enum.take(99)
#=> ["guppy", "ox", "bear", "lion"]
enum.next
#=> "guppy"
enum.next
#=> "ox"
enum.next
#=> "bear"
enum.next
#=> "lion"
enum.next
#=> StopIteration: iteration reached an end