Class: Enumerator::Product

Inherits:
Enumerator show all
Defined in:
enumerator.c,
enumerator.c

Overview

Enumerator::Product generates a Cartesian product of any number of enumerable objects. Iterating over the product of enumerable objects is roughly equivalent to nested each_entry loops where the loop for the rightmost object is put innermost.

innings = Enumerator::Product.new(1..9, ['top', 'bottom'])

innings.each do |i, h|
  p [i, h]
end
# [1, "top"]
# [1, "bottom"]
# [2, "top"]
# [2, "bottom"]
# [3, "top"]
# [3, "bottom"]
# ...
# [9, "top"]
# [9, "bottom"]

The method used against each enumerable object is ‘each_entry` instead of `each` so that the product of N enumerable objects yields an array of exactly N elements in each iteration.

When no enumerator is given, it calls a given block once yielding an empty argument list.

This type of objects can be created by Enumerator.product.

Instance Method Summary collapse

Methods inherited from Enumerator

#+, #each_with_index, #each_with_object, #feed, #next, #next_values, #peek, #peek_values, produce, product, #with_index, #with_object

Methods included from Enumerable

#all?, #any?, #chain, #chunk, #chunk_while, #collect, #collect_concat, #compact, #count, #cycle, #detect, #drop, #drop_while, #each_cons, #each_entry, #each_slice, #each_with_index, #each_with_object, #entries, #filter, #filter_map, #find, #find_all, #find_index, #first, #flat_map, #grep, #grep_v, #group_by, #include?, #inject, #lazy, #map, #max, #max_by, #member?, #min, #min_by, #minmax, #minmax_by, #none?, #one?, #partition, #reduce, #reject, #reverse_each, #select, #slice_after, #slice_before, #slice_when, #sort, #sort_by, #sum, #take, #take_while, #tally, #to_a, #to_h, #uniq, #zip

Constructor Details

#Enumerator::Product.new(*enums) ⇒ Enumerator

Generates a new enumerator object that generates a Cartesian product of given enumerable objects.

e = Enumerator::Product.new(1..3, [4, 5])
e.to_a #=> [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]]
e.size #=> 6


3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
# File 'enumerator.c', line 3494

static VALUE
enum_product_initialize(int argc, VALUE *argv, VALUE obj)
{
    struct enum_product *ptr;
    VALUE enums = Qnil, options = Qnil;

    rb_scan_args(argc, argv, "*:", &enums, &options);

    if (!NIL_P(options) && !RHASH_EMPTY_P(options)) {
        rb_exc_raise(rb_keyword_error_new("unknown", rb_hash_keys(options)));
    }

    rb_check_frozen(obj);
    TypedData_Get_Struct(obj, struct enum_product, &enum_product_data_type, ptr);

    if (!ptr) rb_raise(rb_eArgError, "unallocated product");

    ptr->enums = rb_ary_freeze(enums);

    return obj;
}

Instance Method Details

#each {|...| ... } ⇒ Object #eachObject

Iterates over the elements of the first enumerable by calling the “each_entry” method on it with the given arguments, then proceeds to the following enumerables in sequence until all of the enumerables are exhausted.

If no block is given, returns an enumerator. Otherwise, returns self.

Overloads:

  • #each {|...| ... } ⇒ Object

    Yields:

    • (...)

    Returns:



3653
3654
3655
3656
3657
3658
3659
# File 'enumerator.c', line 3653

static VALUE
enum_product_each(VALUE obj)
{
    RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_product_enum_size);

    return enum_product_run(obj, rb_block_proc());
}

#initialize_copy(orig) ⇒ Object

:nodoc:



3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
# File 'enumerator.c', line 3517

static VALUE
enum_product_init_copy(VALUE obj, VALUE orig)
{
    struct enum_product *ptr0, *ptr1;

    if (!OBJ_INIT_COPY(obj, orig)) return obj;
    ptr0 = enum_product_ptr(orig);

    TypedData_Get_Struct(obj, struct enum_product, &enum_product_data_type, ptr1);

    if (!ptr1) rb_raise(rb_eArgError, "unallocated product");

    ptr1->enums = ptr0->enums;

    return obj;
}

#inspectString

Returns a printable version of the product enumerator.

Returns:



3708
3709
3710
3711
3712
# File 'enumerator.c', line 3708

static VALUE
enum_product_inspect(VALUE obj)
{
    return rb_exec_recursive(inspect_enum_product, obj, 0);
}

#rewindObject

Rewinds the product enumerator by calling the “rewind” method on each enumerable in reverse order. Each call is performed only if the enumerable responds to the method.

Returns:



3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
# File 'enumerator.c', line 3669

static VALUE
enum_product_rewind(VALUE obj)
{
    struct enum_product *ptr = enum_product_ptr(obj);
    VALUE enums = ptr->enums;
    long i;

    for (i = 0; i < RARRAY_LEN(enums); i++) {
        rb_check_funcall(RARRAY_AREF(enums, i), id_rewind, 0, 0);
    }

    return obj;
}

#sizeInteger, ...

Returns the total size of the enumerator product calculated by multiplying the sizes of enumerables in the product. If any of the enumerables reports its size as nil or Float::INFINITY, that value is returned as the size.

Returns:



3574
3575
3576
3577
3578
# File 'enumerator.c', line 3574

static VALUE
enum_product_size(VALUE obj)
{
    return enum_product_total_size(enum_product_ptr(obj)->enums);
}