"地图"是一个循环吗?

DVK*_*DVK 39 perl loops map semantics

回答这个问题时,我意识到我不确定Perl是否map可以被视为循环?

一方面,它像循环一样嘎嘎叫/走路(O(n)工作,可以通过等效循环轻松地重写,并且符合常见定义="一系列不断重复的指令").

另一方面,map通常不在Perl的控制结构中列出,其中循环是其中的子集.例如http://en.wikipedia.org/wiki/Perl_control_structures#Loops

所以,我正在寻找的是一个正式的理由来确信一方与另一方.到目前为止,前者(它是一个循环)对我来说听起来更有说服力,但我对我从未在Perl循环列表中提到的"map"这一事实感到困扰.

Car*_*ers 30

map是一种比循环更高层次的概念,借鉴了函数式编程.它并没有说"从头到尾一个接一个地对这些项目中的每个项目调用此函数",它说"在所有这些项目上调用此函数".它可能被实现为一个循环,但这不是重点 - 它也可能是异步实现的 - 它仍然是map.

另外,它本身并不是一个真正的控制结构 - 如果在其实现中使用循环的每个perl函数都列在"循环"下会怎样?仅仅因为使用循环实现某些东西,并不意味着它应该被认为是它自己的循环类型.

  • perl认为映射控制结构.它是LOGOP mapwhile,它是一个控制分支操作 (5认同)
  • @DVK,我想你可以这么说,但我更多地指的是循环和地图之间的抽象差异.Map是一个函数式编程概念,表示(对这些事情这样做),而循环是一个可用于实现map的低级控制结构. (2认同)

pil*_*row 26

不,从我的角度来看,它不是一个循环.

(perl)循环的特征是它们可以被打破(last)或恢复(next,redo). map不能:

map { last } qw(stack overflow);  # ERROR!  Can't "last" outside a loop block
Run Code Online (Sandbox Code Playgroud)

错误消息表明perl本身不会将评估的块视为循环块.


Eri*_*rom 19

从学术角度来看,可以根据地图的定义来制作两者.如果它总是按顺序迭代,那么foreach可以通过map使两个等价来模拟循环.映射的一些其他定义可能允许执行列表的顺序执行(在线程之间划分工作甚至是单独的计算机).foreach构造可以做同样的事情.

但就Perl 5而言,map总是按顺序执行,使其等效于循环.表达式的内部结构map $_*2, 1, 2, 3导致以下执行顺序操作码显示map内部构建为类似while控件结构:

OP  enter
COP nextstate
OP  pushmark
SVOP const IV 1
SVOP const IV 2
SVOP const IV 3
LISTOP mapstart
LOGOP (0x2f96150) mapwhile  <-- while still has items, shift one off into $_
    PADOP gvsv GV *_            
    SVOP const IV 2             loop body
    BINOP multiply              
    goto LOGOP (0x2f96150)  <-- jump back to the top of the loop
LISTOP leave 
Run Code Online (Sandbox Code Playgroud)


Cha*_*ens 12

map函数不是Perl中的循环.这可以通过失败可以清楚地看到next,redolast里面map:

perl -le '@a = map { next if $_ %2; } 1 .. 5; print for @a'
Can't "next" outside a loop block at -e line 1.
Run Code Online (Sandbox Code Playgroud)

要在a中实现所需的效果map,必须返回一个空列表:

perl -le '@a = map { $_ %2 ? () : $_ } 1 .. 5; print for @a'
2
4
Run Code Online (Sandbox Code Playgroud)

我认为转换是类似构造的更好名称map.它将一个列表转换为另一个列表.类似的功能mapList::Util::reduce,但它不是将列表转换为另一个列表,而是将列表转换为标量值.通过使用单词转换,我们可以讨论这两个高阶函数的共同方面.

也就是说,它通过访问列表中的每个成员来工作.这意味着它的行为很像循环,并且取决于您对"循环"的定义是否合格.注意,我的定义意味着此代码中没有循环:

#!/usr/bin/perl

use strict;
use warnings;

my $i = 0;
FOO:
    print "hello world!\n";
goto FOO unless ++$i == 5;
Run Code Online (Sandbox Code Playgroud)

Perl实际上在其文档中定义了单词循环:

   loop
       A construct that performs something repeatedly, like a roller
       coaster.
Run Code Online (Sandbox Code Playgroud)

根据这个定义,它map是一个循环,因为它反复预先形成它的块; 但是,它还定义了"循环控制语句"和"循环标签":

   loop control statement
       Any statement within the body of a loop that can make a loop
       prematurely stop looping or skip an "iteration".  Generally you
       shouldn't try this on roller coasters.

   loop label
       A kind of key or name attached to a loop (or roller coaster) so
       that loop control statements can talk about which loop they want to
       control.
Run Code Online (Sandbox Code Playgroud)

我认为调用map循环是不精确的,因为next它的亲属被定义为循环控制语句而它们无法控制map.

这只是玩文字.描述map为类似循环是一种非常有效的方式来介绍某人.甚至文档也map使用foreach循环作为其示例的一部分:

               %hash = map { get_a_key_for($_) => $_ } @array;

           is just a funny way to write

               %hash = ();
               foreach (@array) {
                   $hash{get_a_key_for($_)} = $_;
               }
Run Code Online (Sandbox Code Playgroud)

这一切都取决于上下文.当你试图让他或她理解这个概念时,将某人的乘法描述为重复加法很有用,但你不希望他或她继续这样想.你会希望他或她学习乘法规则,而不是总是转换回加法规则.

  • @DVK`next`,`redo`和`last`被定义为循环控制语句.这意味着任何循环都可以由它们控制.但是魔鬼在这里的定义.查看我在答案中添加的额外信息. (2认同)

FMc*_*FMc 11

你的问题转向了分类问题.至少在一种解释下,询问是否map循环就像询问是否map是"循环"的子集.以这种方式框架,我认为答案是否定的.虽然map和Loop有许多共同点,但是有很多不同之处.

我们在现实世界中一直遇到这样的关系 - 彼此有很多共同点的东西,但它们都不是另一个的完美子集.

 -----------------------------------------
|Things that iterate?                     |
|                                         |
|      ------------------                 |
|     |map()             |                |
|     |                  |                |
|     |          --------|----------      |
|     |          |       |          |     |
|     |          |       |          |     |
|      ------------------           |     |
|                |                  |     |
|                |              Loop|     |
|                 ------------------      |
|                                         |
 -----------------------------------------
Run Code Online (Sandbox Code Playgroud)

  • @DVK:你问过!map确实是单词的大多数意义上的迭代器,因为它将列表元素别名为`$ _`. (5认同)

zak*_*rya 10

map是一个高阶函数.这同样适用于grep.Book Higher-Order Perl详细解释了这个想法.

看到讨论转向实施细节而不是概念,我感到很遗憾.


Amb*_*ber 3

map本身通常使用某种循环来实现(通常是在迭代器上循环),但由于它是一个更高级别的结构,因此它通常不包含在较低级别控制结构的列表中。