Perl 按值对哈希进行排序
Perl Sorting Hash by Value of Value
我有一个看起来像
的散列
'Jarrod' => {
'Age' => '25 ',
'Occupation' => Student
},
'Elizabeth' => {
'Age' => '18',
'Occupation' => Student
},
'Nick' => {
'Age' => '32 ',
'Occupation' => Lawyer
},
我正在尝试按年龄对它们进行排序,这样它看起来像
'Nick' => {
'Age' => '32 ',
'Occupation' => Lawyer
},
'Jarrod' => {
'Age' => '25 ',
'Occupation' => Student
},
'Elizabeth' => {
'Age' => '18',
'Occupation' => Student
},
但我似乎无法弄清楚如何访问超过 Age 的任何内容。订购哈希键时如何访问值的值?
具有所示数据的散列变量 %h
可以按照所需的顺序进行处理,如
use Data::Dump qw(pp); # to print out a complex data structure
say "$_->[0] => ", pp($_) for
map { [ $_, $h{$_} ] }
sort { $h{$b}->{Age} <=> $h{$a}->{Age} }
keys %h;
打印什么(来自下面的完整程序)
Nick => { Age => "32 ", Occupation => "Lawyer" }
Jarrod => { Age => "25 ", Occupation => "Student" }
Elizabeth => { Age => 18, Occupation => "Student" }
请注意,我们不能对散列进行“排序”,然后就这样,因为散列本质上是随机的。†但是我们当然可以通过并按特定顺序处理元素,例如上面的示例。
解释:sort takes pairs of elements of a submitted list in turn, available in variables $a
and $b
, and then runs the block of code we provide, so to compare他们按照规定。在这里,我们根据键 Age
.
处的值比较并排序元素
不过,输出只是这样排序的那些键!所以我们然后通过 map
传递它,它将每个键与其 hashref 值和 returns 这些对组合在一起,每个都在一个 arrayref 中。那是用来打印它们的,作为实际处理的占位符。
一个完整的程序
use warnings;
use strict;
use feature 'say';
use Data::Dump qw(dd pp);
my %h = (
'Jarrod' => {
'Age' => '25 ',
'Occupation' => 'Student'
},
'Elizabeth' => {
'Age' => '18',
'Occupation' => 'Student'
},
'Nick' => {
'Age' => '32 ',
'Occupation' => 'Lawyer'
},
);
say "$_->[0] => ", pp($_->[1]) for
map { [ $_, $h{$_} ] } sort { $h{$b}->{Age} <=> $h{$a}->{Age} } keys %h;
或者,对于可行的模板,更改为
my @sorted_pairs =
map { [ $_, $h{$_} ] } sort { $h{$b}->{Age} <=> $h{$a}->{Age} } keys %h;
for my $key_data (@sorted_pairs) {
say $key_data->[0], ' => ', pp $key_data->[1]; # or just: dd $key_data;
# my ($name, $data) = @$key_data;
# Process $data (a hashref) for each $name
}
一旦我们开始为有序数据构建更合适的数据结构,就会有多种选择,包括每个名称的 one-person hashrefs,以正确的顺序存储在数组中。最终,所有这些都可以很好地组织在 class.
中
请注意 Sort::Key 如何使排序部分变得不那么麻烦
use Sort::Key qw(rnkeysort); # rn... -> Reverse Numerical
my @pairs = map { [ $_, $h{$_} ] } rnkeysort { $h{$_}->{Age} } keys %h;
排序越复杂(或特定),此模块的好处就越大,它有许多针对通用标准的特定功能。
如果这些年龄以整数形式给出,则有 ikeysort
(和 rikeysort
),然后这些是无符号整数,因此有 ukeysort
(和 rukeysort
).
† 例如参见 [=26=]。
您无法对哈希进行排序。哈希的元素本质上是无序的。
如果你只想按顺序访问散列的元素,你可以通过获取和排序键来实现。
for my $name (
sort { $people{ $b }{ age } <=> $people{ $a }{ age } }
keys( %people )
) {
my $person = $people{ $name };
...
}
或
use Sort::Key qw( rikeysort );
for my $name (
rikeysort { $people{ $_ }{ age } }
keys( %people )
) {
my $person = $people{ $name };
...
}
如果您需要一个有序的结构,您可以先将数据转换为一组人。
my @unordered_people =
map { +{ name => $_, %{ $people{ $_ } } }
keys( %people );
然后排序。
my @ordered_people =
sort { $b->{ age } <=> $a->{ age } }
@unordered_people;
或
use Sort::Key qw( rikeysort );
my @ordered_people =
rikeysort { $_->{ age } }
@unordered_people;
我有一个看起来像
的散列
'Jarrod' => {
'Age' => '25 ',
'Occupation' => Student
},
'Elizabeth' => {
'Age' => '18',
'Occupation' => Student
},
'Nick' => {
'Age' => '32 ',
'Occupation' => Lawyer
},
我正在尝试按年龄对它们进行排序,这样它看起来像
'Nick' => {
'Age' => '32 ',
'Occupation' => Lawyer
},
'Jarrod' => {
'Age' => '25 ',
'Occupation' => Student
},
'Elizabeth' => {
'Age' => '18',
'Occupation' => Student
},
但我似乎无法弄清楚如何访问超过 Age 的任何内容。订购哈希键时如何访问值的值?
具有所示数据的散列变量 %h
可以按照所需的顺序进行处理,如
use Data::Dump qw(pp); # to print out a complex data structure
say "$_->[0] => ", pp($_) for
map { [ $_, $h{$_} ] }
sort { $h{$b}->{Age} <=> $h{$a}->{Age} }
keys %h;
打印什么(来自下面的完整程序)
Nick => { Age => "32 ", Occupation => "Lawyer" }
Jarrod => { Age => "25 ", Occupation => "Student" }
Elizabeth => { Age => 18, Occupation => "Student" }
请注意,我们不能对散列进行“排序”,然后就这样,因为散列本质上是随机的。†但是我们当然可以通过并按特定顺序处理元素,例如上面的示例。
解释:sort takes pairs of elements of a submitted list in turn, available in variables $a
and $b
, and then runs the block of code we provide, so to compare他们按照规定。在这里,我们根据键 Age
.
不过,输出只是这样排序的那些键!所以我们然后通过 map
传递它,它将每个键与其 hashref 值和 returns 这些对组合在一起,每个都在一个 arrayref 中。那是用来打印它们的,作为实际处理的占位符。
一个完整的程序
use warnings;
use strict;
use feature 'say';
use Data::Dump qw(dd pp);
my %h = (
'Jarrod' => {
'Age' => '25 ',
'Occupation' => 'Student'
},
'Elizabeth' => {
'Age' => '18',
'Occupation' => 'Student'
},
'Nick' => {
'Age' => '32 ',
'Occupation' => 'Lawyer'
},
);
say "$_->[0] => ", pp($_->[1]) for
map { [ $_, $h{$_} ] } sort { $h{$b}->{Age} <=> $h{$a}->{Age} } keys %h;
或者,对于可行的模板,更改为
my @sorted_pairs =
map { [ $_, $h{$_} ] } sort { $h{$b}->{Age} <=> $h{$a}->{Age} } keys %h;
for my $key_data (@sorted_pairs) {
say $key_data->[0], ' => ', pp $key_data->[1]; # or just: dd $key_data;
# my ($name, $data) = @$key_data;
# Process $data (a hashref) for each $name
}
一旦我们开始为有序数据构建更合适的数据结构,就会有多种选择,包括每个名称的 one-person hashrefs,以正确的顺序存储在数组中。最终,所有这些都可以很好地组织在 class.
中请注意 Sort::Key 如何使排序部分变得不那么麻烦
use Sort::Key qw(rnkeysort); # rn... -> Reverse Numerical
my @pairs = map { [ $_, $h{$_} ] } rnkeysort { $h{$_}->{Age} } keys %h;
排序越复杂(或特定),此模块的好处就越大,它有许多针对通用标准的特定功能。
如果这些年龄以整数形式给出,则有 ikeysort
(和 rikeysort
),然后这些是无符号整数,因此有 ukeysort
(和 rukeysort
).
† 例如参见 [=26=]。
您无法对哈希进行排序。哈希的元素本质上是无序的。
如果你只想按顺序访问散列的元素,你可以通过获取和排序键来实现。
for my $name (
sort { $people{ $b }{ age } <=> $people{ $a }{ age } }
keys( %people )
) {
my $person = $people{ $name };
...
}
或
use Sort::Key qw( rikeysort );
for my $name (
rikeysort { $people{ $_ }{ age } }
keys( %people )
) {
my $person = $people{ $name };
...
}
如果您需要一个有序的结构,您可以先将数据转换为一组人。
my @unordered_people =
map { +{ name => $_, %{ $people{ $_ } } }
keys( %people );
然后排序。
my @ordered_people =
sort { $b->{ age } <=> $a->{ age } }
@unordered_people;
或
use Sort::Key qw( rikeysort );
my @ordered_people =
rikeysort { $_->{ age } }
@unordered_people;