为什么用 uniq 排序不能一起工作 [英] why does sort with uniq not work together

查看:47
本文介绍了为什么用 uniq 排序不能一起工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下脚本:

use strict;
use List::MoreUtils qw/uniq/;
use Data::Dumper;

my @x = (3,2);
my @y = (4,3);

print "unique results \n";
print Dumper([uniq(@x,@y)]);

print "sorted unique results\n";
print Dumper([sort uniq(@x,@y)]);

输出为

unique results 
$VAR1 = [
          3,
          2,
          4
        ];
sorted unique results
$VAR1 = [
          2,
          3,
          3,
          4
        ];

所以看起来这种排序不适用于 uniq.我不明白为什么.

So it looks that sort does not work with uniq. I did not understand why.

我用 -MO=Deparse 运行了 perl 脚本并得到了

I ran the perl script with -MO=Deparse and got

use List::MoreUtils ('uniq');
use Data::Dumper;
use strict 'refs';
my(@x) = (3, 2);
my(@y) = (4, 3);
print "unique results \n";
print Dumper([uniq(@x, @y)]);
print "sorted unique results\n";
print Dumper([(sort uniq @x, @y)]);

我的解释是 perl 决定从 uniq(@x,@y) 中删除括号并使用 uniq 作为排序函数.

My interpretation is that perl decided to remove the parentheses from uniq(@x,@y) and using uniq as a function of sort.

为什么 perl 决定这样做?

Why did perl decide to do it?

我怎样才能避免这些和类似的陷阱?

How can i avoid these and similar pitfalls?

谢谢,大卫

推荐答案

sort 内置 接受一个子程序名称或块作为第一个参数,它传递了两个项目.然后它必须返回一个数字来确定项目之间的顺序.这些片段都做同样的事情:

The sort builtin accepts a subroutine name or block as first argument which is passed two items. It then must return a number which determines the order between the items. These snippets all do the same:

use feature 'say';
my @letters = qw/a c a d b/;

say "== 1 ==";
say for sort @letters;

say "== 2 ==";
say for sort { $a cmp $b } @letters;

say "== 3 ==";
sub func1 { $a cmp $b }
say for sort func1 @letters;

say "== 4 ==";
sub func2 ($$) { $_[0] cmp $_[1] }  # special case for $$ prototype
say for sort func2 @letters;

注意函数名和列表之间没有逗号,注意Perl中的括号主要用于确定优先级——sort func1 @letterssort func1(@letters) 是一样的,都没有执行 func1(@letters).

Notice that there isn't any comma between the function name and the list, and note that the parens in Perl are primarly used to determine precedence – sort func1 @letters and sort func1 (@letters) are the same, and neither executes func1(@letters).

要消除歧义,请在函数名称前放置一个 +:

To disambiguate, place a + before the function name:

sort +uniq @letters;

为避免此类意外行为,最好的解决方案是在您不确定某个内置函数的行为时阅读文档——不幸的是,许多内置函数都有一些特殊的解析规则.

To avoid such unexpected behaviour, the best solution is to read the docs when you aren't sure how a certain builtin behaves – unfortunately, many have some special parsing rules.

这篇关于为什么用 uniq 排序不能一起工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆