And*_* T. 4 arrays sorting perl
我想让用户可以更改数据结构中的排序顺序(asc / desc)。据我所知,这是通过更改代码$a和的顺序来完成的$b,但是我想以编程方式更改它,以避免重复的代码。
我做了一个工作的例子:
use 5.018;
use warnings;
# Supply any argument to change sorting order
my $sorting_direction = $ARGV[0];
my $data = {
'item1' => {
'min' => 4,
'size' => 825,
'max' => 256,
},
'item2' => {
'min' => 4,
'size' => 130,
'max' => 65,
},
};
if (defined $sorting_direction) {
foreach my $item (sort { $$data{$a}{'size'} <=> $$data{$b}{'size'} } keys %{$data} ) {
say "$item\t", $$data{$item}{'size'};
}
} else {
foreach my $item (sort { $$data{$b}{'size'} <=> $$data{$a}{'size'} } keys %{$data} ) {
say "$item\t", $$data{$item}{'size'};
}
}
Run Code Online (Sandbox Code Playgroud)
提供任何参数都会更改sorting_direction。如果没有条件,我可以这样做吗?
由于<=>的值为-1、0或1,您可以乘以-1以获得相反的排序顺序。
因此,如果您的$ sorting_direction为1或-1,请使用
$sorting_direction * ( $$data{$a}{'size'} <=> $$data{$b}{'size'} )
Run Code Online (Sandbox Code Playgroud)
通用解决方案是使用不同的比较功能。
my %sorters = (
by_size_asc => sub { $data->{$a}{size} <=> $data->{$b}{size} },
by_size_desc => sub { $data->{$b}{size} <=> $data->{$a}{size} },
# ...
);
@ARGV
or die("usage\n");
my $sorter = $sorters{$ARGV[0]}
or die("Invalid sort function \"$ARGV[0]\".\n");
my @sorted_keys = sort $sorter keys(%$data);
Run Code Online (Sandbox Code Playgroud)
您还可以使用其他排序函数,例如在使用出色的Sort :: Key模块时。
use Sort::Key qw( ikeysort rikeysort );
my %sorters = (
by_size_asc => sub { ikeysort { $data->{$_}{size} } @_ },
by_size_desc => sub { rikeysort { $data->{$_}{size} } @_ },
# ...
);
@ARGV
or die("usage\n");
my $sorter = $sorters{$ARGV[0]}
or die("Invalid sort function \"$ARGV[0]\".\n");
my @sorted_keys = $sorter->( keys(%$data) );
Run Code Online (Sandbox Code Playgroud)