Editing Topic: RCR262 Project: RCR | RCRchive home

RCR 262: more enumerator functionality

submitted by Kristof Bastiaensen on Thu Aug 05 2004 04:41:25 PM -0700

Status: pending


Abstract

This RCR proposes two additions for "enumerator": to_enum with a block, and Enumerable#enum_if.

Problem

The enumerator library provides a way to create an enumerable from any method. This RCR adds even more convenient functionality.

Proposal

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]

Analysis

Currently filtering can be done using Enumerable#select, but this can be inefficient when it is used with large data, because a temporary array needs to be created. The enumerable created by enum_if will also reflect any changes made to the original object. Using to_enum with a block provides a powerful way of creating custum enumerables that can perform any transformation on the original data.

Implementation

A patch is available which was created by Nobu Nokada



Back to RCRchive.


RCR Submission page and RCRchive powered by Ruby, Apache, RuWiki (modified), and RubLog