将迭代计算转换为迭代器 - 这叫做什么?

问题描述:

这必须是一个通用的代码转换,所以我很惊讶,我不能轻松找到它的名称,也不知道如何做到最好。将迭代计算转换为迭代器 - 这叫做什么?

原代码(伪):

sub generate_array { 
    for(i=0,n=0;i<X;++i) 
    for(j=0;j<Y;++j) 
     for(k=0;k<p[i][j];++k,++n) 
     a[n] = calculation(i,j,k,n,p); 
    return a; 
} 

m=generate_array(); 
for(i=0;i<size(m);++i) 
    if (some_cond(m[i]) break; 
    work_with(m[i]); 

对于时间效率的原因,我想偷懒-EVAL数组,而不是这样的:

sub array_start() {...} 
sub array_next() {... return val} 

array_start(); 
while (m = array_next()) 
    if some_cond(m) break; 
    work_with(m); 

是的,这就是所谓的 “懒评价” 一般(设计模式),但是不是这种特定的基本类型的代码转换称为更具体的东西?我还查找了“迭代器”和“工厂”设计模式,以及“循环展开”,但没有什么是我所谈论的概念适合的概念。有任何想法吗?我错过了什么?引导赞赏。

更新

答案是 “发电机” 为如下。至于代码的“转换”,上面的核心变化是a[n] = - >yield,当然使用任何语法定义了一个生成器而不是子例程。但是,如果你的语言不支持它并且/或者你不想使用第三方包来实现它,那么也可以“手工”实现这个想法(至少对于这个简单的例子) unnesting”所有的循环:

sub array_next { 
    if (++k >= p[i][j]) 
    k = 0; 
    if (++j >= Y) 
     j = 0; 
     if (++i >= X) 
     return false 
    return calculation(i,j,k,p) 
} 

sub array_start { 
    i = j = k = 0; 
} 

需要注意的是,虽然需要被正确处理的区别:变量(ijk)已经成为全球性的,或者至少暴露。

+0

枚举?我认为(可能是错误的),MoveNext,MovePrev,开始,结束属于枚举器样式/名称... – MaxOvrdrv

+0

谢谢。到目前为止,我只发现“枚举器”被描述为“迭代器”的实现接口,并且总是绑定到现有的可枚举集合(而不是延迟计算的值),但也许还有更多... –

+0

myeah没有真正的术语......你基本上只是循环遍历一个数组,并检查一个条件......没有什么特别的或具体的。我以为你指的是你循环的方式(MoveNext而不是For循环)......对不起,我帮不了你。 – MaxOvrdrv

你在这里做什么并不完全是懒惰评价,因为它通常指的是某些表达式的延迟评估,这在功能性编程中很常见。从Lazy Evaluation*的文章:

[...]懒惰的评价,或致电按需要的是一项评价战略需要它的值,直到其 延迟一个表达式的计算[...]

你在这里建造什么非常适合术语发电机。从Generators*的文章:

[...]发电机是可以用来控制回路的 迭代行为的特别程序。实际上,所有的发生器都是 迭代器。生成器与返回数组的函数非常相似,因为生成器具有参数,可以调用,并且生成一系列值。然而,与其构建包含所有值的数组 并将它们一次全部返回,发生器 每次只产生一个值,这需要较少的内存,并且允许调用者立即开始处理前几个值。

如果生成的序列是无限的,则生成器通常被称为。然而,术语流也用于按需计算的有限序列。

+1

是的,就是这样!作为一个纯粹主义者(为了我自己的教育和效率控制),我将在上面的代码中实现这个概念,解开所有的循环,而不是找到一个能够提供“良品”能力的软件包。但很高兴知道这种设计需求以前已被认可,命名和解决! –