我想循环一个数组的片段。我基本上有两个主要选择。
ar.each_with_index{|e,i|
next if i < start_ind
break if i > end_ind
foo(e)
#maybe more code...
}
我认为更优雅的另一种选择是运行:
ar[start_ind..end_ind].each{|e|
foo(e)
#maybe more code...
}
我担心Ruby可能会在引擎盖下创建一个巨大的阵列并进行大量的内存分配。或者是否有一些“更聪明”的东西没有创建副本?
答案 0 :(得分:3)
你可以做一个索引值的循环......不像你的第二个解决方案那么优雅,但经济实惠。
null
答案 1 :(得分:1)
您可能想参考方法&#39; C源代码,但读取代码需要一些时间。我可以帮助你吗
首先:each_index
它在C中的源代码很棘手,但归结为类似于&#39;每个&#39;看起来像
VALUE rb_ary_each(VALUE ary) {
long i;
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
for (i=0; i<RARRAY_LEN(ary); i++) {
rb_yield(RARRAY_AREF(ary, i));
}
return ary;
}
它本身不会在内部创建任何其他数组。它实际上做的是简单地循环遍历元素,获取每个元素并将其传递到提供的块(rb_yield部分)。您提供的块内实际上是一个不同的故事。
第二:[...]。每个
你实际上必须注意到它是两个函数调用。第二个是每个&#39;对我们没什么兴趣,因为它在上面描述了第一个函数调用是&#39; []&#39;。从逻辑上讲,你希望它输出一个子数组作为变量,它必须至少是临时存储的。
让我们验证一下。 C的源代码相当长,但对你来说最重要的是:
VALUE rb_ary_aref(int argc, const VALUE *argv, VALUE ary) {
// some code
if (argc == 2) {
beg = NUM2LONG(argv[0]);
len = NUM2LONG(argv[1]);
if (beg < 0) {
beg += RARRAY_LEN(ary);
}
return rb_ary_subseq(ary, beg, len);
}
// some more code
}
它实际上是一个函数调用,如ar [start_ind,end_ind]而不是ar [start_ind..end_ind]。差异并不重要,但这种方式更容易理解。
回答你问题的事情称为&#34; rb_ary_subseq&#34;。正如您可能从其名称中猜测或从其来源中学习,它实际上确实创建了一个新数组。因此,它会在大小等于或小于给定数组的情况下创建副本。
您想要考虑功能调用的计算成本,但问题是关于内存。