2009-04-13 107 views
5

我想排序一个散列实际上有一个散列作为一个值。例如:如何通过Perl中的键对散列哈希进行排序?

my %hash1=(
    field1=>"", 
    field2=>"", 
    count=>0, 
); 
my %hash2; 
$hash2{"asd"}={%hash1}; 

,我插入大量的哈希以%hash2%hash2不同的计数值。

如何根据计数值hash1%hash1进行排序?

有没有办法做到这一点,而不手动执行quicksort,例如与Perl的排序功能?

+0

你的意思是你想通过从HASH2的值数排序的哈希值(如HASH1)的名单? – Jagmal 2009-04-13 06:24:31

+0

是Jagmal,这意味着我想对$ hash2 {“asd”} {count}进行排序。 – systemsfault 2009-04-13 06:29:26

回答

10
my @hash1s = sort {$a->{count} <=> $b->{count}} values %hash2; 
+0

我试过这种方式,但得到以下警告: [警告]:在数值比较中使用未初始化的值(<=>) – systemsfault 2009-04-13 06:48:13

+0

我的答案和我的评论答案的代码段在测试时适用于我即使使用-w和“use strict”)。 – 2009-04-13 07:01:15

+0

由于一个或多个哈希值对'count'键没有任何价值,所以您会收到该警告。如果你想把它们计为0,你可以对{($ a - > {count} || 0)进行排序<=>($ b - > {count} || 0)} values%hash2; – nohat 2009-04-13 07:04:23

1

如果你想通过从HASH2的值数排序的哈希值(如HASH1)的列表中,这可能会帮助:

@sorted_hash1_list = sort sort_hash_by_count_key($a, $b) (values (%hash2); 


# This method can have any logic you want 
sub sort_hash_by_count_key { 
    my ($a, $b) = @_; 
    return $a->{count} <=> $b->{count}; 
} 
0

对于很多的情况下是如何排序的作品见http://perldoc.perl.org/functions/sort.html在Perl中。

这里是一个例子..试图读取,而不是完美。

#!/usr/bin/perl 
# Sort Hash of Hashes by sub-hash's element count. 
use warnings; 
use strict; 


my $hash= { 
      A=>{C=>"D",0=>"r",T=>"q"} 
      ,B=>{} 
      ,C=>{E=>"F",G=>"H"} 
      }; 

sub compareHashKeys {0+(keys %{$hash->{$a}}) <=> 0+(keys %{$hash->{$b}}) } 

my @SortedKeys = sort compareHashKeys keys %{$hash}; 
print join ("," , @SortedKeys) ."\n"; 
6

perlfaq4,答案"http://faq.perl.org/perlfaq4.html#How_do_I_sort_a_hash"有你最需要的放在一起你的代码的信息。

你可能也想看看排序的章节学习Perl

克里斯有一个完全正确的答案,虽然我讨厌使用values这样的。一个更熟悉的方式做同样的事情是要经过顶级哈希的密钥,但排序第二级重点:

my @sorted_hashes = 
    sort { $hash2->{$a}{count} <=> $hash2->{$b}{count} } 
    keys %hash2; 

我做这种方式,因为它是有点不太令人费解。


如何对散列进行排序(可选择使用值而不是键)?

(贡献的布莱恩d FOY)

要排序的散列,与键启动。在这个例子中,我们给出了排序函数的关键字列表,然后将它们用ASCIIbet进行比较(这可能会受到您的语言环境设置的影响)。输出列表具有按ASCII顺序排列的键。一旦我们拥有了密钥,我们就可以通过它们来创建一个报告,按ASCII顺序列出密钥。

my @keys = sort { $a cmp $b } keys %hash; 

foreach my $key (@keys) 
    { 
    printf "%-20s %6d\n", $key, $hash{$key}; 
    } 

虽然我们可以在sort()块中获得更多花式。我们可以用它们计算一个值,并将该值用作比较,而不是比较键。

例如,为了让我们的报表顺序不区分大小写,我们在双引号字符串中使用\ L序列使所有内容都为小写。 sort()块然后比较小写的值以确定按照何种顺序放置键。

my @keys = sort { "\L$a" cmp "\L$b" } keys %hash; 

注:如果计算是昂贵或哈希有很多元素,你可能想看看使用Schwartzian变换缓存的计算结果。

如果我们想用散列值进行排序,我们使用散列键来查找它。我们仍然拿出一个键列表,但这次他们按照它们的价值排序。

my @keys = sort { $hash{$a} <=> $hash{$b} } keys %hash; 

从那里我们可以变得更加复杂。如果散列值相同,我们可以在散列键上提供第二排序。

my @keys = sort { 
    $hash{$a} <=> $hash{$b} 
     or 
    "\L$a" cmp "\L$b" 
    } keys %hash; 
0

要按数字排序使用< =>并为字符串使用cmp。

# sort by the numeric count field on inner hash 
# 
foreach my $key (sort {$hash2{$a}->{'count'} <=> $hash2{$b}->{'count'}} keys %hash2) { 
    print $key,$hash2{$key}->{'count'},"\n"; 
} 

# sort by the string field1 (or field2) on the inner hash 
# 
foreach my $key (sort {$hash2{$a}->{'field1'} cmp $hash2{$b}->{'field1'}} keys %hash2) { 
    print $key,$hash2{$key}->{'field1'},"\n"; 
} 

反序简单地交换$ a和$ b:

# sort by the numeric count field on inner hash 
# 
foreach my $key (sort {$hash2{$a}->{'count'} <=> $hash2{$b}->{'count'}} keys %hash2) { 
    print $key,$hash2{$key}->{'count'},"\n"; 
} 

# sort by the string field1 (or field2) on the inner hash 
# 
foreach my $key (sort {$hash2{$a}->{'field1'} cmp $hash2{$b}->{'field1'}} keys %hash2) { 
    print $key,$hash2{$key}->{'field1'},"\n"; 
} 
相关问题