【发布时间】:2011-09-23 04:25:18
【问题描述】:
在Ruby - Compare two Enumerators elegantly,有人说
zip 的问题在于它 在内部创建数组,不管 你通过什么 Enumerable 。有 输入长度的另一个问题 参数
我查看了 YARV 中 Enumerable#zip 的实现,并看到了
static VALUE
enum_zip(int argc, VALUE *argv, VALUE obj)
{
int i;
ID conv;
NODE *memo;
VALUE result = Qnil;
VALUE args = rb_ary_new4(argc, argv);
int allary = TRUE;
argv = RARRAY_PTR(args);
for (i=0; i<argc; i++) {
VALUE ary = rb_check_array_type(argv[i]);
if (NIL_P(ary)) {
allary = FALSE;
break;
}
argv[i] = ary;
}
if (!allary) {
CONST_ID(conv, "to_enum");
for (i=0; i<argc; i++) {
argv[i] = rb_funcall(argv[i], conv, 1, ID2SYM(id_each));
}
}
if (!rb_block_given_p()) {
result = rb_ary_new();
}
/* use NODE_DOT2 as memo(v, v, -) */
memo = rb_node_newnode(NODE_DOT2, result, args, 0);
rb_block_call(obj, id_each, 0, 0, allary ? zip_ary : zip_i, (VALUE)memo);
return result;
}
我对以下内容的理解正确吗?
检查所有参数是否都是数组,如果是,则将一些对数组的间接引用替换为直接引用
for (i=0; i<argc; i++) {
VALUE ary = rb_check_array_type(argv[i]);
if (NIL_P(ary)) {
allary = FALSE;
break;
}
argv[i] = ary;
}
如果它们不都是数组,则改为创建枚举器
if (!allary) {
CONST_ID(conv, "to_enum");
for (i=0; i<argc; i++) {
argv[i] = rb_funcall(argv[i], conv, 1, ID2SYM(id_each));
}
}
仅在未给出块时创建数组数组
if (!rb_block_given_p()) {
result = rb_ary_new();
}
如果一切都是数组,则使用zip_ary,否则使用zip_i,并在每组值上调用一个块
/* use NODE_DOT2 as memo(v, v, -) */
memo = rb_node_newnode(NODE_DOT2, result, args, 0);
rb_block_call(obj, id_each, 0, 0, allary ? zip_ary : zip_i, (VALUE)memo);
如果没有给出块,则返回数组数组,否则返回 nil (Qnil)?
return result;
}
【问题讨论】:
标签: c ruby array-merge yarv