类 Enumerator::Product

Enumerator::Product 生成任意数量的可枚举对象的笛卡尔积。遍历可枚举对象的积大致等同于嵌套的 each_entry 循环,其中最右侧对象的循环放在最内层。

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"]

对每个可枚举对象使用的方法是 `each_entry` 而不是 `each`,因此 N 个可枚举对象的积在每次迭代中产生一个包含正好 N 个元素的数组。

当没有给出枚举器时,它调用给定的块一次,产生一个空参数列表。

这种类型的对象可以通过 Enumerator.product 创建。

公共类方法

Enumerator::Product.new(*enums) → enum 点击切换源代码

生成一个新的枚举器对象,该对象生成给定可枚举对象的笛卡尔积。

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
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_obj_freeze(enums);

    return obj;
}

公共实例方法

each { |...| ... } → obj 点击切换源代码
each → 枚举器

通过对第一个可枚举对象调用 “each_entry” 方法(使用给定的参数)来遍历第一个可枚举对象的元素,然后依次继续进行后续的可枚举对象,直到所有可枚举对象都耗尽。

如果没有给出块,则返回一个枚举器。否则,返回 self。

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());
}
inspect → string 点击切换源代码

返回产品枚举器的可打印版本。

static VALUE
enum_product_inspect(VALUE obj)
{
    return rb_exec_recursive(inspect_enum_product, obj, 0);
}
rewind → obj 点击切换源代码

通过以相反的顺序对每个可枚举对象调用 “rewind” 方法来重绕产品枚举器。仅当可枚举对象响应该方法时才执行每个调用。

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;
}
size → int, Float::INFINITY 或 nil 点击切换源代码

返回通过将产品中可枚举对象的大小相乘计算出的枚举器产品的总大小。如果任何可枚举对象将其大小报告为 nil 或 Float::INFINITY,则返回该值作为大小。

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