gpt4 book ai didi

perl - 为什么我的排序不能在 Perl 中工作?

转载 作者:行者123 更新时间:2023-12-05 01:24:11 25 4
gpt4 key购买 nike

我从未使用过 Perl,但我需要完成这个练习。我的任务是以几种不同的方式对数组进行排序。我得到了一个测试脚本。该脚本将数组放在一起,并为其排序的每个阶段打印语句。我把它命名为 foo.pl:

use strict;
use warnings;
use MyIxHash;

my %myhash;
my $t = tie(%myhash, "MyIxHash", 'a' => 1, 'abe' => 2, 'cat'=>'3');
$myhash{b} = 4;
$myhash{da} = 5;
$myhash{bob} = 6;

print join(", ", map { "$_ => $myhash{$_}" } keys %myhash) . " are the starting key => val pairs\n";

$t->SortByKey; # sort alphabetically
print join(", ", map { "$_ => $myhash{$_}" } keys %myhash) . " are the alphabetized key => val pairs\n";

$t->SortKeyByFunc(sub {my ($a, $b) = @_; return ($b cmp $a)}); # sort alphabetically in reverse order
print join(", ", map { "$_ => $myhash{$_}" } keys %myhash) . " are the reverse alphabetized key => val pairs\n";

$t->SortKeyByFunc(\&abcByLength); # use abcByLength to sort
print join(", ", map { "$_ => $myhash{$_}" } keys %myhash) . " are the abcByLength sorted key => val pairs\n";

print "Done\n\n";


sub abcByLength {
my ($a, $b) = @_;

if(length($a) == length($b)) { return $a cmp $b; }
else { return length($a) <=> length($b) }
}

Foo.pl 使用一个名为 MyIxHash 的包,我为它创建了一个名为 MyIxHash.pm 的模块。该脚本按字母顺序运行:“SortByKey”,我通过模块中的“IxHash”包继承了它。最后两种是给我带来问题的。当我创建的 sub: "SortKeyByFunc"在数组上运行时,它传入数组和一个子例程作为参数。我试图接受这些论点并将它们与变量相关联。

最终排序应该是按字符串长度排序,然后按字母顺序排序。在 foo.pl 的底部提供了一个子程序,名称为“abcByLength”。与反向 alpha 排序一样,此子例程作为参数传递给我的 SortKeyByFunc 子例程。

对于这两种类型,似乎实际的排序工作已经为我完成了,我只需要将这个子例程应用于我的数组。

我的主要问题似乎是,如果可能的话,我不知道如何获取我的子例程参数并通过它作为参数运行我的数组。我在我的阵列上错误地运行我的方法?

package MyIxHash;
#use strict;
use warnings;
use parent Tie::IxHash;
use Data::Dumper qw(Dumper);

sub SortKeyByFunc {
#my $class = shift;
my ($a, $b) = @_;

#this is a reference to the already alphabetaized array being passed in
my @letters = $_[0][1];

#this is a reference to the sub being passed in as a parameter
my $reverse = $_[1];

#this is my variable to contain my reverse sorted array
my @sorted = @letters->$reverse();

return @sorted;
}

1;

最佳答案

"My problem occurs where I try: my @sorted = @letters->$reverse(); I've also tried: my @sorted = sort {$reverse} @letters;"

你真的很亲近;正确的语法是:

my $reverse = sub { $b cmp $a };
# ...
my @sorted = sort $reverse @letters;

还要注意,出于历史原因,sort 将参数传递给(稍微)神奇的全局变量 $a$ 中的比较函数b,不在 @_ 中,所以你不需要(实际上也不应该)做 my ($a, $b) = @_; 在您的 sortsubs 中(除非您使用原型(prototype)声明它们;请参阅 perldoc -f sort 了解详细信息)。


编辑:如果给你一个比较函数,由于某种原因确实期望它的参数在 @_ 中,你可以' t 更改该函数的定义,那么您最好的选择可能是将其包装在这样的闭包中:

my $fixed_sortsub = sub { $weird_sortsub->($a, $b) };

my @sorted = sort $fixed_sortsub @letters;

或者简单地说:

my @sorted = sort { $weird_sortsub->($a, $b) } @letters;

编辑 2: 啊,我看到了/a 问题。当你写:

my @letters = $_[0][1];

你最终得到的是一个包含任何 $_[0][1] 的单元素数组,大概是 array reference .您应该立即取消引用它,如下所示:

my @letters = @{ $_[0][1] };

或者只是暂时保留作为引用,并在使用时取消引用:

my $letters = $_[0][1];
# ...
my @sorted = sort $whatever @$letters;

编辑3:一旦你设法对键进行排序,那么,正如黄昏在他的原始答案中所指出的那样,你还需要调用 Reorder()父类中的方法,Tie::IxHash实际更改键的顺序。另外,第一行:

my ($a, $b) = @_;

在应该是一个接受代码引用的对象方法中完全不合适(事实上,词法化 $a$b 是不好的无论如何,如果您想稍后在同一代码块中调用 sort )。它应该是这样的:

my ($self, $sortfunc) = @_;

事实上,与其列举所有似乎与您的原始代码有问题的地方相比,修复它可能更容易:

package MyIxHash;
use strict;
use warnings;
use parent 'Tie::IxHash';

sub SortKeyByFunc {
my ($self, $sortfunc) = @_;

my @unsorted = $self->Keys();

my @sorted = sort { $sortfunc->($a, $b) } @unsorted;

$self->Reorder( @sorted );
}

1;

或者简单地说:

sub SortKeyByFunc {
my ($self, $sortfunc) = @_;

$self->Reorder( sort { $sortfunc->($a, $b) } $self->Keys() );
}

(Ps. 我现在明白为什么比较函数被指定为在 @_ 而不是全局变量 $a$b 其中 sort 通常把它们放在:这是因为比较函数属于不同的包,而 $a$bnot神奇到每个包都一样> 可以解决,但是使用 caller 需要一些非常重要的技巧。)

(Pps。请在您提交练习时感谢我和黄昏/Stack Overflow。祝您学习 Perl 好运 - 相信我,拥有这将是一项有用的技能。)

关于perl - 为什么我的排序不能在 Perl 中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14422066/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com