i在perl中的结构:
#!/usr/bin/perl
use strict;
use warnings;
my %hash = (
'firstitem' => {
'1' => ["A","99"],
'2' => ["B","88"],
'3' => ["C","77"],
},
'seconditem' => {
'3' => ["C","100"],
'4' => ["D","200"],
'5' => ["E","300"],
},
);
我正在寻找一种在每个哈希数组中找到最大数字和最小数字的方法。因此,输出将为
firstitem: max:99, min:77
seconditem: max:300, min:100
我的想法是先对辅助键进行排序,然后在for循环中进行气泡排序或其他方式。看起来不是很优雅和聪明。
foreach my $k1 (keys %hash) {
my $second_hash_ref = $hash{$k1};
my @sorted_k2 = sort { $a <=> $b } keys %{$second_hash_ref};
foreach my $i (0..$#sorted_k3){
#bubble sort or other sort
}
}
list :: util是提供min
和max
功能的核心模块:
use strict;
use warnings;
use List::Util qw(min max);
my %hash = (
'firstitem' => {
'1' => ["A","99"],
'2' => ["B","88"],
'3' => ["C","77"],
},
'seconditem' => {
'3' => ["C","100"],
'4' => ["D","200"],
'5' => ["E","300"],
},
);
for my $key (keys(%hash)) {
my @numbers = map { $_->[1] } values(%{$hash{$key}});
printf("%s: max: %d, min: %dn", $key, max(@numbers), min(@numbers));
}
输出:
firstitem: max: 99, min: 77
seconditem: max: 300, min: 100
你几乎在那里。
到达第二层后,您需要的是数字的整个列表,因此能够找到最大和最小地块。由于您需要子键内所有数组的极端值,因此无需在第二级键上迭代。
另外,您可以获取所有数组内容,除非保证数字在特定位置。然后将grep
与标量:: util :: look_like_number一起过滤出来不是数字的元素。
最后,对键进行排序没有好处。
use warnings;
use strict;
use feature 'say';
use Scalar::Util 'looks_like_number';
use List::MoreUtils 'minmax';
my %hash = (
'firstitem' => {
'1' => ["A","99"], '2' => ["B","88"], '3' => ["C","77"],
},
'seconditem' => {
'3' => ["C","100"], '4' => ["D","200"], '5' => ["E","300"],
},
);
foreach my $k1 (keys %hash)
{
my @nums =
grep { looks_like_number($_) }
map { @{ $hash{$k1}{$_} } }
keys %{$hash{$k1}};
my ($min, $max) = minmax @nums;
say "$k1: max = $max, min = $min";
}
这打印了预期值。如果您的真实哈希完全如图所示,则可以直接通过values %{$hash{$k1}}
提取Arrayref,并使用map { @$_ }
取消它们。
由于您需要两种极端的良好拟合度是从List :: Moreutils中的minmax
,这是" 最有效的算法"。该算法的性能已在模块的XS版本中完全实现,而Perl版本则具有一定的开销。
还请注意核心列表:: UTIL模块,其中单个min
和max
在其他实用程序中。