Comment on this RCR (edit wiki page) | RCRchive home

RCR 242: Add collect_flatten and collect_flatten! to Array

submitted by NickJohnson on Sun Apr 11 2004 12:36:40 PM -0700

Status: withdrawn


Abstract

A new method of class array, tentatively named collect_flatten and collect_flatten! would ease certain programming constructs, especially in mathematics.

Problem

Although Array's collect method is very useful, it falls short for blocks which would like to add more than one element to the resultant array.

For example, suppose I want to construct the Koch curve (see http://en.wikipedia.org/wiki/Koch_curve). I would start by creating a class for a line segment in R^2 space. Then, with the current implementation of Array, I would create an array containing one such line segment, and call:

setOfLineSegments=[LineSegment.new(...)] setOfLineSegments.collect! do |ls| [ # each line segment is # replaced by 4 LineSegment.new(...) LineSegment.new(...) LineSegment.new(...) LineSegment.new(...) ] end setOfLineSegments.flatten!

Such iterative approximation of an infinite and recursively defined set is common. Such code would be more readable with collect_flatten and collect_flatten! methods of array.

Proposal

I propose that two methods be added to class Array: collect_flatten and collect_flatten!, which each combine the effects of collect and flatten.

Analysis

This would cause no incompatibilities with previous versions of Ruby.

These methods could be implemented as either a call to collect and then to flatten, or as a call to collect and concat (either would be ok with me).

I feel that the collect and flatten pair makes more intuitive sense, though the collect and concat pair may be faster.

Implementation

class Array def collect_flatten(&block) r = collect(&block) r.flatten end def collect_flatten!(&block) collect!(&block) flatten! end end

Have you considered inject, like this?

segments = [1, 2, 3]
segments = segments.inject([]) do |result, seg|
  # compute new segments
  result + [seg, seg, seg]
end
p segments  # [1, 1, 1, 2, 2, 2, 3, 3, 3]

-- Simon Strandgaard

Add comments here



Vote for this RCR

Strongly opposed [3]
Opposed [0]
Neutral [0]
In favor [0]
Strongly advocate [0]

Change the status of this RCR to:

accepted

rejected

withdrawn


Have you considered <tt>inject</tt>, like this?

segments = [1, 2, 3]
segments = segments.inject([]) do |result, seg|
  # compute new segments
  result + [seg, seg, seg]
end
p segments  # [1, 1, 1, 2, 2, 2, 3, 3, 3]

-- Simon Strandgaard

Add comments here


Back to RCRchive.


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