在Perl中使用map或grep函数

14

我现在已经全职写Perl代码几个月了(生物信息学),并且一直在努力提高我的技能。就在今天,我意识到我从来没有使用过map或grep。回顾我的代码,我意识到这些工具可以为我节省一些行代码,但只是以foreach循环的灵活性为代价。我的问题如下:

您是否遇到过任何情况,使用map或grep比使用foreach/for循环带来了显着优势(除了节省一两行代码)?

感谢您的时间!


1
一个 map 可以与更大的表达式内联。foreach 不能。 - brian d foy
2个回答

40

这里有一个例子:Schwartzian Transform

@sorted = map  { $_->[0] }
          sort { $a->[1] cmp $b->[1] }
          map  { [$_, foo($_)] }
          @unsorted;

你可以使用大量的foreach循环来实现,但是你必须分开它们才能弄清楚发生了什么;一旦你看到了Schwartzian Transform,你就会立刻认出这个习惯用法。

总体而言,我认为mapgrep很好,因为它们允许你清晰、简洁地表示你的意图,而不需要多层语法。如果你看到一个map,那么你知道正在进行一些简单的数据结构转换;如果你看到一个grep,那么你知道正在进行一些过滤/选择。你可以使用所有的foreach,但是你的代码意图不如使用mapgrep清晰;你甚至可以使用ifgoto来完成所有操作,但是你的意图将被埋在更多的语法和状态跟踪中。


非常感谢您简明扼要地回答了我的问题。我将来肯定会在以后使用Schwartzian Transfers,并且一直以来都不得不通过一些技巧来解决这类问题。谢谢! - wespiserA
5
请注意Tanktalus关于List::MoreUtils的建议,这个软件包提供了一些有用的工具,可以帮助你让代码更符合你的意图。 - mu is too short
4
第二段加一分。Perl 有许多在技术上是可以互换的命令,因此选择那些语义最清晰地传达你今后阅读代码的人所想要表达的意图。 - Dave Sherohman

16

我经常使用mapgrep,还有List::MoreUtils中的applyfirstany等等。通常来说,它们会解释代码在做什么而不是怎么做。

一般来说,当我的代码读起来与规范相同时,它更可能是正确的,并且也更可能处理边缘情况。 Perl让我比以前使用的任何语言都做得更好,并且我充分利用了它。

例如,如果我的规范说,如果$blah在某个列表中,我将执行foo(),那么我的代码也会完全按照这种方式读取:

foo() if any { $_ eq $blah } some_list();

对于其余工具,理念相同。代码和规范看起来非常相似,这也是 Perl 的一大优点。


这个回答中所解释的概念(特别是“代码在做什么而不是怎么做”这一评论)背后的思想是函数式编程:http://en.wikipedia.org/wiki/Functional_programming - tokland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接