Perl对数组的哈希进行排序

4

我有一个数组的哈希值,看起来像这样:

{ $key, [$val1, $val2] }

我想通过数组的第二个值进行数字排序,并打印整个哈希表。我看过 Schwartzian 转换的帖子,但没有看到完全符合我要求的。我也对语法和如何将排序后的值映射回原始 {$key, [$val1, $val2] } 格式感到非常困惑。希望能得到帮助!

四分之一,肯定吧?(虽然这也不是什么好消息!) - Dave Cross
1
@davorg 有5个问题,1个被接受。不确定SO如何计算这个比率,看起来确实很奇怪。 - TLP
Schwartzian转换处理计算值的排序。您想为每个元素计算它们一次,而不是2 * nlogn次。您已经计算出要排序的值$hash->{$key}[1]。您不需要Schwartzian转换。 - Axeman
@TLP 在进行该计算之前,会有一定的延迟来使用新的问题。 - Brad Gilbert
在你对Perl有更全面的了解之前,请勿尝试使用Schwartzian变换 - Brad Gilbert
@TLP 抱歉,我假设在投票下面的勾选标记也需要至少15个声望。已修复! - kurifu
2个回答

14

我不太确定你指的是什么,但这是如何在哈希内实现对数组值进行排序的方法:

my %hash = ( 'key1' => [ 1, 2 ], 'key2' => [ 2, 3 ] );

for my $key ( sort { $hash{$a}[1] <=> $hash{$b}[1] } keys %hash ) {
    print "$key => '", join(", ", @{$hash{$key}}), "'\n";
}

完美,像魔法一样运行。谢谢!我还在适应这种语法,所以如果这似乎是初级问题,请原谅。 - kurifu

7

如果你确实想使用Schwartzian-Transform,以下是一种方法:

#!/usr/bin/perl
use Data::Dump qw(dump);

my %hash = (k1 => [1, 2], k2 => [24, 5], k3 => [5, 1]);
foreach(
        sort { $a->[1] <=> $b->[1] }
        map { [$_, $hash{$_}->[1] ] } keys %hash) {
    say $_->[0],' => ',dump$hash{$_->[0]};
}

输出:

k3 => [5, 1]
k1 => [1, 2]
k2 => [24, 5]

NB:

我只是举例说明了Schwartzian Transform的用法。但正如评论中所说,在问题中解释的情况下并不需要使用它,ST在每个数组元素排序前都需要计算一些内容,因此可以节省成本。对于提出的问题,没有要计算的内容,所以不要在这里使用ST。


1
我们真的需要在这里使用Schwartzian Transform吗?好像$hash{$_}->[1]不是一个昂贵的操作。 - TLP
3
@TLP:OP 特别询问 Schwartzian 变换,因此我认为提供一个实现示例很重要。然而,我认为在算法中应该附上特定情况的解释,因为这种表达方式可能会让 Perl 初学者感到有些不安。 - flesk
2
@flesk 人们总是要求一些他们不需要的疯狂事情。= P 使用他的数据,Schwartzian变换实际上增加了成本。我想展示它是正确的,但在这种情况下不需要的话最好提一下。 - TLP
@TLP:没错。现在的答案比之前更好了。 - flesk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接