sort uniq(@stuff)没有排序,也没有重复数据删除

时间:2016-08-29 16:46:38

标签: perl sorting

  

有些代码让我感到抒情,
  结果略显歇斯底里   我寻求的sort输出,
  所有元素uniq ue,
  但结果呢?远非临床。

有问题的代码

use strict;
use warnings;

sub uniq { my %seen; grep ! $seen{$_}++, @_ }

my @test = ();
for ( 1 .. 3 ) {
  @test = sort uniq( @test, qw/ d d c c b b a a / );
  print "@test\n";
}

输出

d d c c b b a a
d d c c b b a a d d c c b b a a
d d c c b b a a d d c c b b a a d d c c b b a a

修复

一组额外的括号恢复奇偶校验:

@test = sort( uniq( @test, qw/ d d c c b b a a / ) );  # a b c d

通过-MO=Deparse运行这两行有助于解释额外问题的影响 - 它迫使翻译人员将RHS视为sort LIST而不是sort SUBNAME LIST

# Doesn't work as intended (sort SUBNAME LIST)
@test = (sort uniq @test, ('d', 'd', 'c', 'c', 'b', 'b', 'a', 'a'));

# Works as intended (sort LIST)
@test = sort(uniq(@test, ('d', 'd', 'c', 'c', 'b', 'b', 'a', 'a')));

我的问题

  • 为什么需要额外的括号?

    uniq会返回一个列表,所以我希望

    sort uniq( @stuff );
    

    等同于

    sort LIST
    

2 个答案:

答案 0 :(得分:2)

虽然它很少使用,但perldoc -f sort中列出的第一个表单是sort SUBNAME LIST。即sort的可选第二个参数是用作排序比较器的函数的名称。当然,LIST可能有也可能没有括号,而且空格是免费的,所以

 sort uniq( @test, qw/ d d c c b b a a / )

表示使用函数(@test, qw/ d d c c b b a a /)作为比较器对列表uniq进行排序。由于uniq的结果独立于$a$b并且它没有原型,因此它始终返回undef,其排序视为0,并且排序响应此断言通过不改变任何事物的顺序,一切都是平等的(因为它是一个稳定的排序,至少从5.8开始)。

答案 1 :(得分:1)

uniq被视为子名称,因为它是标识符或不是函数名称的限定标识符。没有进行实际检查以查看该子实际是否存在(尽管在这种情况下它会发现子存在)。

sort之后需要跟一个函数名称或不是标识符或限定标识符的东西,以便从sort SUBNAME LIST语法中取消资格。