2016-07-25 108 views
1

嘗試這樣的:perl的名單:: AllUtils uniq的和排序

perl -Mv5.14 -MList::AllUtils=uniq -E 'my(@x) = qw(2 3 1 2); say "@x"; my(@y) = uniq @x; say "@y"' 

它正確打印

2 3 1 2 
2 3 1 

現在要有序輸出,所以嘗試:

perl -Mv5.14 -MList::AllUtils=uniq -E 'my(@x) = qw(2 3 1 2); say "@x"; my(@y) = sort uniq @x; say "@y"' 

令人驚訝的是打印:

2 3 1 2 
2 1 3 2 

切換uniq的順序和sort

perl -Mv5.14 -MList::AllUtils=uniq -E 'my(@x) = qw(2 3 1 2); say "@x"; my(@y) = uniq sort @x; say "@y"' 

給出正確的結果

2 3 1 2 
1 2 3 

因此,使用MO=Deparse進行比較。

第1:

perl -MO=Deparse -Mv5.14 -MList::AllUtils=uniq -E 'my(@x) = qw(2 3 1 2); say "@x"; my(@y) = uniq @x; say "@y"' 
sub BEGIN { 
    require v5.14; 
} 
use List::AllUtils (split(/,/u, 'uniq', 0)); 
use strict; 
use feature 'current_sub', 'evalbytes', 'fc', 'postderef_qq', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval'; 
my(@x) = ('2', '3', '1', '2'); 
say join($", @x); 
my(@y) = &uniq(@x); 
say join($", @y); 
-e syntax OK 

第二:

perl -MO=Deparse -Mv5.14 -MList::AllUtils=uniq -E 'my(@x) = qw(2 3 1 2); say "@x"; my(@y) = sort uniq @x; say "@y"' 
sub BEGIN { 
    require v5.14; 
} 
use List::AllUtils (split(/,/u, 'uniq', 0)); 
use strict; 
use feature 'current_sub', 'evalbytes', 'fc', 'postderef_qq', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval'; 
my(@x) = ('2', '3', '1', '2'); 
say join($", @x); 
my(@y) = (sort uniq @x); 
say join($", @y); 
-e syntax OK 

第三:

perl -MO=Deparse -Mv5.14 -MList::AllUtils=uniq -E 'my(@x) = qw(2 3 1 2); say "@x"; my(@y) = uniq sort @x; say "@y"' 
sub BEGIN { 
    require v5.14; 
} 
use List::AllUtils (split(/,/u, 'uniq', 0)); 
use strict; 
use feature 'current_sub', 'evalbytes', 'fc', 'postderef_qq', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval'; 
my(@x) = ('2', '3', '1', '2'); 
say join($", @x); 
my(@y) = &uniq(sort(@x)); 
say join($", @y); 
-e syntax OK 

的區別是uniq子程序是如何調用:

my(@y) = (sort uniq @x); # sort uniq @x 
my(@y) = &uniq(sort(@x)); # uniq sort @x 

我的理解比uniq是由List::AllUtils提供的子程序和sort是內置的功能,但使用uniq爲:

my(@y) = &uniq(sort(@x)); 

似乎並不對我來說非常intutive。

我必須在&uniq(...)表格中使用它,例如,與&和括號? Coudl有人請添加一些關於?

回答

2

如果你運行它use strictuse warnings它告訴你什麼是錯的。

use strict; 
use warnings; 
use feature 'say'; 
use List::AllUtils 'uniq'; 

my (@x) = qw(2 3 1 2); 
say "@x"; 
my (@y) = sort uniq @x; 
say "@y"; 

這給了警告排序子程序沒有在返回一個值。 sort認爲uniq是它應該用來排序列表的子例程。

The sort documentation解釋了這一點。

排序SUBNAME LIST
排序塊列表
排序列表

你也可以給它一個子的名字。直接使用該子名稱(即,不是作爲字符串,或作爲代碼引用)有點違反直覺,但這就是它應該是的。文檔中甚至有一個例子。

# sort using explicit subroutine name 
sub byage { 
    $age{$a} <=> $age{$b}; # presuming numeric 
} 
my @sortedclass = sort byage @class; 

所以在這種情況下,它把你的uniq不是_call uniq(@x)和排序使用默認sort行爲的返回值,而是它確實排序@x使用uniq作爲排序功能


您可以sort忽略子名稱和前面加上一個+標誌使用返回值來代替。

my (@x) = qw(2 3 1 2); 
say "@x"; 
my (@y) = sort +uniq @x; 
say "@y"; 

__END__ 
2 3 1 2 
1 2 3 

現在沒有警告。 sort +uniq(@x)也有效,並且更易於閱讀。

+0

使用-Mv5.14啓用'strict',甚至您的示例中的'warnings'也不會顯示任何警告。至少對我來說 - 使用'v5.24.0'。 – kobame

+0

@ kobame嗯,這很奇怪。我有5.20。但那仍然是發生的事情。警告或不警告。你可以通過給它一個子名 – simbabque

+1

'sort(uniq(@x))'覆蓋缺省行爲,只要'uniq'後面沒有空格就行了 – Borodin