【发布时间】:2015-01-22 21:54:37
【问题描述】:
为了比较我知道在 perl 中长度相同(并且具有可预测顺序)的数组的每个元素,我们有 each_arrayref 可以添加到有用的子例程中或直接使用:
use List::AllUtils qw/each_arrayref/;
my ($arr1, $arr2) = ( [10, 31, 12], [20, 21, 14] );
my $iterate_elems = each_arrayref($arr1, $arr2);
while ( my ($x, $y) = $iterate_elems->() ) {
say $x lt $y ? "$x is lower " : "$x is higher" ;
}
或单线剪切和粘贴:
perl -MList::AllUtils=each_arrayref -E '
my $iter = each_arrayref([10, 31, 12], [20, 21, 14]);
while ( my ($x, $y) = $iter->() ){
say $x lt $y ? "$x lower" : "$x higher"}'
但这似乎有点尴尬,而且并非完全万无一失。我尝试使用像$iterate_elems 这样的描述性术语作为迭代函数参考来帮助。也许我没有使用它来让它看起来很明显。
在 perl6 中有 metaoperators 允许进行各种相当简洁和酷的列表比较和修改。这让我认为必须有一种方法可以在 perl5 中使用运算符重载来做到这一点。任何人都可以评论这个智慧吗?似乎更容易理解以将运算符应用于一系列列表而不是遍历列表以应用运算符的方式编写的代码。也许创造性地使用map 或List::MoreUtils 的apply 可以达到同样的效果。
特别欢迎惊人的 perl6 代码示例。
【问题讨论】:
-
也许我错过了你的问题的重点,但是......如果你知道长度是一样的,
for my $i (0 .. $#array1) { say $array1[$i], $array2[$i]; }有什么问题? -
通常数组或列表会更大,并且可能想要对元素进行更多比较,我认为
each_arrayref应该可以做到这一点。但是是的,越简单越好。 -
我想我还是没明白。具有更多元素或需要进行更多比较的数组如何更改循环中的逻辑?也许一个更具体的例子是为了......
-
$ perl6 -e 'say (10, 31, 12) Zcmp (20, 21, 4 )'导致Less More More -
@ThisSuitIsBlackNot 点很好——我的例子太简单了。我对
each_arrayref(以及List::MoreUtils和朋友中的一些其他功能)的理解是,它们提供了一种包装更直接的结构(如循环)的方法,因此它们可以以不同的方式“扩展”:例如用于比较数组元素的嵌套foreach循环是清晰和熟悉的,但是对于三个或更多数组,或者来自 arrayrefs 等哈希的键数组,$iterator->()coderef 可以节省括号。 ;-)