class 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 创建。
Public Class Methods
Source
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");
RB_OBJ_WRITE(obj, &ptr->enums, rb_ary_freeze(enums));
return obj;
}
生成一个新的枚举器对象,该对象生成给定可枚举对象的笛卡尔积。
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
Public Instance Methods
Source
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());
}
通过在第一个可枚举对象上使用给定的参数调用“each_entry”方法来遍历其元素,然后依次处理后续的可枚举对象,直到所有可枚举对象都被耗尽。
如果没有给出块,则返回一个枚举器。否则,返回 self。
Source
static VALUE
enum_product_inspect(VALUE obj)
{
return rb_exec_recursive(inspect_enum_product, obj, 0);
}
返回产品枚举器的可打印版本。
Source
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;
}
通过反向调用产品中每个可枚举对象的“rewind”方法来倒带产品枚举器。仅当可枚举对象响应该方法时才会执行每次调用。
Source
static VALUE
enum_product_size(VALUE obj)
{
return enum_product_total_size(enum_product_ptr(obj)->enums);
}
返回枚举器乘积的总大小,该大小通过将乘积中可枚举对象的大小相乘来计算。如果任何可枚举对象报告其大小为 nil 或 Float::INFINITY,则返回该值作为大小。