我发现Ruby中有一个相对较新的特性允许链接迭代 - 换句话说,代替each_with_indices { |x,i,j| ... }
你可以each.with_indices { |x,i,j| ... }
,其中#each
返回{{1} } object和Enumerator
导致包含额外的yield参数。
因此,Enumerator#with_indices
有自己的方法Enumerator
,大概是对于一维对象source found here。但我无法找到使其适应其他物体的最佳方法。
要明确,并回应评论: Ruby现在没有#with_index
- 它只有一个#each_with_indices
。 (这就是为什么我要创建一个。)
一系列问题,他们自己被束缚住了:
#each_with_index
?include Enumerable
类,派生自EnumerableN
,但Enumerable
转换为#with_index
?#with_indices
),如下例所示。示例:
dtype
所以,将我的三个问题合并为一个:我如何用C语言写一个VALUE nm_dense_each(VALUE nm) {
volatile VALUE nm = nmatrix; // Not sure this actually does anything.
DENSE_STORAGE* s = NM_STORAGE_DENSE(nm); // get the storage pointer
RETURN_ENUMERATOR(nm, 0, 0);
if (NM_DTYPE(nm) == nm::RUBYOBJ) { // matrix stores VALUEs
// matrix of Ruby objects -- yield those objects directly
for (size_t i = 0; i < nm_storage_count_max_elements(s); ++i)
rb_yield( reinterpret_cast<VALUE*>(s->elements)[i] );
} else { // matrix stores non-Ruby data (int, float, etc)
// We're going to copy the matrix element into a Ruby VALUE and then operate on it. This way user can't accidentally
// modify it and cause a seg fault.
for (size_t i = 0; i < nm_storage_count_max_elements(s); ++i) {
// rubyobj_from_cval() converts any type of data into a VALUE using macros such as INT2FIX()
VALUE v = rubyobj_from_cval((char*)(s->elements) + i*DTYPE_SIZES[NM_DTYPE(nm)], NM_DTYPE(nm)).rval;
rb_yield( v ); // yield to the copy we made
}
}
}
链接到上面的#with_indices
方法?
我并不特别希望任何人觉得我要求他们为我编码,但如果你真的想要,我们很乐意让你参与我们的项目。 =)
但是,如果你在网上其他地方知道如何做到这一点,那就完美了 - 或者如果你能用语言解释,那也很可爱。
答案 0 :(得分:1)
#with_index
是Enumerator
的一种方法:http://ruby-doc.org/core-1.9.3/Enumerator.html#method-i-with_index
我想你可以创建一个Enumerator
的子类#with_indices
并让你的#each
返回该类的实例?这是我想到的第一件事,虽然你的普查员可能必须与原始课程相结合......
答案 1 :(得分:0)
因为你说你也对Ruby语言学感兴趣,而不仅仅是C,让我贡献我的5美分,而不是声称实际回答这个问题。 #each_with_index
和#with_index
已经变得如此惯用,以至于大多数人依赖索引作为数字。因此,如果您以这种方式实施NMatrix#each_with_index
,那么它将提供例如{ |e, i| ... }
。数组[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], ...
作为索引i
,你会让人大吃一惊。此外,如果其他人使用NMatrix#each
方法链接您的#with_index
枚举器,则他们只会收到一个数字作为索引。所以,实际上,你应该得出结论,你需要一个独特的方法来处理2个索引类型(或者更常见的是更高维矩阵的n个索引):
matrix.each_with_indices { |e, indices| ... }
此方法应返回二维(n维)数组indices == [i, j]
。你不应该使用版本:
matrix.each_with_indices { |e, i, j| ... }
至于#with_index
方法,根本不是你关心的问题。如果您的NMatrix
提供了#each
方法(它确实如此),那么#with_index
将会正常使用它,不受您的控制。而且你不需要考虑引入特定于矩阵的#with_indices
,因为#each
本身并不是特定于矩阵,而是任何类型的一维有序集合。最后,很抱歉没有熟练的C程序员来迎合你问题的C相关部分。