0

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?

2
  • Your question is a bit unclear as to your desired outcome or usage. Commented Dec 10, 2021 at 17:09
  • based on my example, I am looking for e4 = words.enum_for(:select, {|x| x.length != 3} or something similar. Commented Dec 11, 2021 at 9:42

2 Answers 2

2

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
Sign up to request clarification or add additional context in comments.

4 Comments

No I wasn't looking for lazy, but I was looking for this Syntax! You saved my evening. This is the way: e4 = words.enum_for.select{|x| x.length != 3} . Amazingly I have not found this syntax in any doc. Thanks!
@Eric what do you mean not documented (Kernel#to_enum words.enum_for creates an each enumerator and then select returns an Array this would be identical to removing the enum_for in this case.
@engineersmnky: that's very clear, but in the case of each.meth the enumerator knows already what's to do. meth works on the return value of each (an enumerator). But in enum_for.meth meth is kind of an argument needed to create the enumerator. That's a little bit weird in my eyes.
I just figured out, that enum_for.meth does not create the custom enumerator. It behaves just like each.meth. That means, the syntax is consistent - but I am still looking for a possibility to create a custom enumerator with enum_for.
0
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

1 Comment

That's clear - my question aimed at the enum_for method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.