Project

General

Profile

Actions

Feature #6636

closed

Enumerable#size

Added by marcandre (Marc-Andre Lafortune) over 12 years ago. Updated about 12 years ago.

Status:
Closed
Target version:
[ruby-core:45805]

Description

Now that it has been made clear that Enumerable#count never calls #size and that we have Enumerable#lazy, let me propose again an API for a lazy way to get the size of an Enumerable: Enumerable#size.

  • call-seq:
  • enum.size # => nil, Integer or Float::INFINITY
  • Returns the number of elements that will be yielded, without going through
  • the iteration (i.e. lazy), or +nil+ if it can't be calculated lazily.
  • perm = (1..100).to_a.permutation(4)
  • perm.size # => 94109400
  • perm.each_cons(2).size # => 94109399
  • loop.size # => Float::INFINITY
  • [42].drop_while.size # => nil

About 66 core methods returning enumerators would have a lazy size, like each_slice, permutation or lazy.take.

A few would have size return nil:
Array#{r}index, {take|drop}_while
Enumerable#find{_index}, {take|drop}_while
IO: all methods

Sized enumerators can also be created naturally by providing a block to to_enum/enum_for or a lambda to Enumerator.new.

Example for to_enum:

class Integer
  def composition
    return to_enum(:composition){ 1 << (self - 1) } unless block_given?
    yield [] if zero?
    downto(1) do |i|
      (self - i).composition do |comp|
        yield [i, *comp]
      end
    end
  end
end

4.composition.to_a
# => [[4], [3, 1], [2, 2], [2, 1, 1], [1, 3], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]]
42.composition.size # => 2199023255552

Example for Enumerator.new:

def lazy_product(*enums)
  sizer = ->{
    enums.inject(1) do |product, e|
      break if (size = e.size).nil?
      product * size
    end
  }
  Enumerator.new(sizer) do |yielder|
    # ... generate combinations
  end
end

lazy_product(1..4, (1..3).each_cons(2)).size # => 8
lazy_product(1..4, (1..3).cycle).size # => Float::INFINITY

Files

enumsize.pdf (131 KB) enumsize.pdf marcandre (Marc-Andre Lafortune), 07/01/2012 05:26 AM

Related issues 2 (0 open2 closed)

Related to Ruby master - Feature #3715: Enumerator#size and #size=Rejected08/19/2010Actions
Related to Ruby master - Bug #7298: Behavior of Enumerator.new different between 1.9.3 and 2.0.0Closedayumin (Ayumu AIZAWA)11/07/2012Actions
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0