【问题标题】:Can I pass arguments to the compare subroutine of sort in Perl?我可以将参数传递给 Perl 中排序的比较子例程吗?
【发布时间】:2010-10-22 09:32:16
【问题描述】:

我正在使用 sort 和我编写的自定义比较子例程:

sub special_compare {
 # calc something using $a and $b
 # return value
}

my @sorted = sort special_compare @list;

我知道最好使用自动设置的$a$b,但有时我希望我的special_compare 获得更多参数,即:

sub special_compare {
 my ($a, $b, @more) = @_; # or maybe 'my @more = @_;' ?
 # calc something using $a, $b and @more
 # return value
}

我该怎么做?

【问题讨论】:

    标签: perl sorting compare


    【解决方案1】:

    使用sort BLOCK LIST 语法,请参阅perldoc -f sort

    如果你已经写了上面的special_compare sub,你可以这样做,例如:

    my @sorted = sort { special_compare($a, $b, @more) } @list;
    

    【讨论】:

    • 您可能需要传递对@more 的引用以阻止它一直被复制。
    • 如果合适的话,或者只是使用内联代码而不是调用子代码。
    【解决方案2】:

    您可以使用闭包代替排序子例程:

    my @more;
    my $sub = sub {        
        # calc something using $a, $b and @more
    };
    
    my @sorted = sort $sub @list;
    

    如果要传递@_ 中要比较的元素,请将子程序的原型设置为($$)。注意:这比非原型子程序慢。

    【讨论】:

    • mscha 的解决方案更干净而且似乎有效。你有什么理由不使用它吗?
    • @David:使用闭包可能更有效。不过我没有运行基准测试。
    • 如果考虑性能并且比较功能很重,请查看Schwartzian transform
    • 这种方法的优点是 $a 和 $b 不会失去它们不被复制的特殊属性。 @mscha 的解决方案将其参数复制到子例程中(我认为...),而此解决方案没有。
    • 我认为 Schwartzian 变换是对阿诺德施瓦辛格引用的又一个晦涩的引用......但是感谢您提供的信息!
    猜你喜欢
    • 2016-11-22
    • 2021-03-09
    • 2019-02-09
    • 2011-01-10
    • 1970-01-01
    • 2019-10-05
    • 1970-01-01
    • 2020-07-10
    • 1970-01-01
    相关资源
    最近更新 更多