to_enum creates an enumerable object from any method. I propose that to_enum can take a block, which enables it to transform the block-output. for example:
powers = 4.to_enum(:times){ |i| i * i}
powers.to_a
=> [0, 1, 4, 9]
A new method Enumerable#enum_if will also be provided to enable powerful filtering possibilities. It will yield the current value if the given block doesn't return false. for example:
(0..4).enum_if { |i| i % 2 == 0 }.to_a
=> [0, 2, 4]
This method can be useful as a replacement for Enumerable#select, where it may be inefficient to create a large temporary array:
large_dataset.enum_if { |d| sometest(d) }.collect do |d|
<some transformations>
end
Any enumerable created by enum_if will reflect any changes made to the original object:
data = ["a", 6, 9, "foo", -19, "fuga", -19, "bar"]
ints = data.enum_if { |i| i.is_a? Numeric }
ints.to_a
=> [6, 9, -19, -19]
data += ["Bear", 20, 3]
ints.to_a
=> [6, 9, -19, -19, 20, 3]
A patch is available which was created by Nobu Nokada
The block idea: this sounds like you want a kind of default map behavior. But isn't the idea to return something which mimics an iterator -- and then (as with an iterator) tell it what to do? This seems maybe a little too magic.
#enum_if: I don't really like the idea of having an alternative #select because of implementation issues. That brings the implementation too directly into the language -- it's too low-level a decision, I think.
-- David Black
obj.to_enum.select{|x| x.isa? Numeric}
works like enum_if that is proposed here?
--matz.
"The block idea: this sounds like you want a kind of default map behavior."
Well, the idea is more to have a kind of transparent map behaviour. In this way you can transform one kind of iterator in another one. You may want to save the enumerable to avoid doing the same transformation on an object over and over again. Someone had also implemented something similar to have a "lazy" iterator. It would be lazy because the block is only executed when a call to the original objects :each method is made.
"obj.to_enum.select{|x| x.isa? Numeric}"
That's nice! I am not sure if it will confuse people who expect Enumerator#select to return an Array (or break something), but I like the idea.
--Kristof Bastiaensen
Back to RCRchive.
RCR Submission page and RCRchive powered by Ruby, Apache, RuWiki (modified), and RubLog