如何在Perl中从哈希中获取小于阈值的第一个值
我有一个散列,其中包含unixtime作为键,volume作为值 我需要从散列中获取unixtime和volume对,其中卷小于我在开始时定义的阈值threshold value,并且该对出现在散列的第一位 以下是我的脚本:如何在Perl中从哈希中获取小于阈值的第一个值,perl,hash,Perl,Hash,我有一个散列,其中包含unixtime作为键,volume作为值 我需要从散列中获取unixtime和volume对,其中卷小于我在开始时定义的阈值threshold value,并且该对出现在散列的第一位 以下是我的脚本: use strict; use warnings; use Data::Dumper; use List::Util qw(reduce); use POSIX qw( strftime ); my $threshold = 20; my %hash = (
use strict;
use warnings;
use Data::Dumper;
use List::Util qw(reduce);
use POSIX qw( strftime );
my $threshold = 20;
my %hash = (
'1596561300' => '19',
'1596561306' => '12',
'1596561312' => '17',
'1596561318' => '20',
'1596561324' => '23',
'1596561330' => '11',
'1596561336' => '16',
'1596561342' => '15',
'1596561348' => '13',
'1596561354' => '17'
);
my $key = reduce { $hash{$a} <= $hash{$b} ? $a : $b } keys %hash;
my $val = $hash{$key};
$key = strftime("%Y-%m-%d %H:%M:%S", localtime($key));
print "Key=>$key :: Value=>$val\n";
但我需要获取小于第一个/最小哈希键中出现的阈值的值
对于上面的示例,它应该获取“1596561300”=>“19”,即:
Key=>2020-08-04 18:15:00 :: Value=>19
我怎么去拿?TIA.我认为您无法避免按键对哈希进行排序:
foreach my $k (sort keys %hash) {
if( $hash{$k} <= $threshold ) {
print "Key=>", strftime("%Y-%m-%d %H:%M:%S", localtime($k)),
":: Value=>", $hash{$k}, "\n";
last;
}
}
我认为您无法避免按键对哈希进行排序:
foreach my $k (sort keys %hash) {
if( $hash{$k} <= $threshold ) {
print "Key=>", strftime("%Y-%m-%d %H:%M:%S", localtime($k)),
":: Value=>", $hash{$k}, "\n";
last;
}
}
您可以反转散列以翻转键和值,然后从阈值向后计数,直到找到一个存在的值 my%reversed=反向%hash; my$Pineder=$threshold-1; $Pionel-直到存在$reversed{$Pionel}; my$key=strftime%Y-%m-%d%H:%m:%S,localtime$reversed{$needle}; 我的$val=$needle; 打印键=>$Key::Value=>$val\n; 我不认为我以前用过,但这似乎比不存在时读得更好 阈值为20的输出为
您可以反转散列以翻转键和值,然后从阈值向后计数,直到找到一个存在的值 my%reversed=反向%hash; my$Pineder=$threshold-1; $Pionel-直到存在$reversed{$Pionel}; my$key=strftime%Y-%m-%d%H:%m:%S,localtime$reversed{$needle}; 我的$val=$needle; 打印键=>$Key::Value=>$val\n; 我不认为我以前用过,但这似乎比不存在时读得更好 阈值为20的输出为
基本上,您需要做的就是通过散列,检查值是否低于阈值,并记住符合该标准的最早时间戳:
#!/usr/bin/env perl
use strict;
use warnings;
use POSIX qw( strftime );
my $threshold = 20;
my %hash = (
'1596561300' => '19',
'1596561306' => '12',
'1596561312' => '17',
'1596561318' => '20',
'1596561324' => '23',
'1596561330' => '11',
'1596561336' => '16',
'1596561342' => '15',
'1596561348' => '13',
'1596561354' => '17'
);
my $earliest;
for (keys %hash) {
# Ignore any entries with a volume above the threshold
next if $hash{$_} >= $threshold;
$earliest //= $_; # Initialize it if it doesn't have a value yet
$earliest = $_ if $_ < $earliest;
}
die "No volumes under threshold" unless defined $earliest;
my $formatted = strftime("%Y-%m-%d %H:%M:%S", localtime($earliest));
print "Key=>$formatted :: Value=>$hash{$earliest}\n";
基本上,您需要做的就是通过散列,检查值是否低于阈值,并记住符合该标准的最早时间戳:
#!/usr/bin/env perl
use strict;
use warnings;
use POSIX qw( strftime );
my $threshold = 20;
my %hash = (
'1596561300' => '19',
'1596561306' => '12',
'1596561312' => '17',
'1596561318' => '20',
'1596561324' => '23',
'1596561330' => '11',
'1596561336' => '16',
'1596561342' => '15',
'1596561348' => '13',
'1596561354' => '17'
);
my $earliest;
for (keys %hash) {
# Ignore any entries with a volume above the threshold
next if $hash{$_} >= $threshold;
$earliest //= $_; # Initialize it if it doesn't have a value yet
$earliest = $_ if $_ < $earliest;
}
die "No volumes under threshold" unless defined $earliest;
my $formatted = strftime("%Y-%m-%d %H:%M:%S", localtime($earliest));
print "Key=>$formatted :: Value=>$hash{$earliest}\n";
通过检查值是否小于阈值以及密钥是否小于上次捕获的密钥,可以在不进行排序的情况下通过哈希 我只是在没有语法检查或编译器的情况下将其抛出:
my $threshold = 20;
my $last;
for my $key (keys %hash) {
if ($hash{$key} <= $threshold && $key < ($last //= $key)) {
$last = $key;
}
}
if ($last) {
printf "Key=>%s :: Value=>%s\n",
strftime("%Y-%m-%d %H:%M:%S",
localtime($last)),$hash{$last};
}
通过检查值是否小于阈值以及密钥是否小于上次捕获的密钥,可以在不进行排序的情况下通过哈希 我只是在没有语法检查或编译器的情况下将其抛出:
my $threshold = 20;
my $last;
for my $key (keys %hash) {
if ($hash{$key} <= $threshold && $key < ($last //= $key)) {
$last = $key;
}
}
if ($last) {
printf "Key=>%s :: Value=>%s\n",
strftime("%Y-%m-%d %H:%M:%S",
localtime($last)),$hash{$last};
}
您可以使用提供的pairmap和unpairs方法 pairmap:类似于perl的map关键字,但将给定的列表解释为大小相等的对列表。它在列表上下文中多次调用块,将$a和$b设置为@kvlist中的连续值对。返回块在列表上下文中返回的所有值的串联,或在标量上下文中返回的项数的计数 unpairs:成对的反函数;此函数获取一个数组引用列表,每个数组引用包含两个元素,并返回每个数组引用对中两个值的展开列表 输出
您可以使用提供的pairmap和unpairs方法 pairmap:类似于perl的map关键字,但将给定的列表解释为大小相等的对列表。它在列表上下文中多次调用块,将$a和$b设置为@kvlist中的连续值对。返回块在列表上下文中返回的所有值的串联,或在标量上下文中返回的项数的计数 unpairs:成对的反函数;此函数获取一个数组引用列表,每个数组引用包含两个元素,并返回每个数组引用对中两个值的展开列表 输出
请注意,只有当所有哈希值都是唯一的时,反转哈希才可靠。如果存在重复项,则使用“反转”将其转换为关键帧会导致关键帧冲突,其中一个将覆盖其他关键帧。在问题的示例数据中,有两个值为17的条目,因此其中一个时间戳丢失。@DaveSherohman true,我没有看到。然而问题是OP想要哪一个。您的解决方案有相同的冲突问题,因为您没有排序。因此,根据Perl版本的密钥顺序,您会得到随机密钥。既然OP没有说他们想要最早的,我想你也在做假设,尽管你的比我的好得多。但我认为问题还不清楚,问题是我需要获取小于第一个/最小散列键中出现的阈值的值,我认为这表明他想要最早的限定时间戳。如果你认为我的答案有问题,请在这里发表评论,因为讨论与你的答案无关。请注意,只有当所有哈希值都为
e独一无二。如果存在重复项,则使用“反转”将其转换为关键帧会导致关键帧冲突,其中一个将覆盖其他关键帧。在问题的示例数据中,有两个值为17的条目,因此其中一个时间戳丢失。@DaveSherohman true,我没有看到。然而问题是OP想要哪一个。您的解决方案有相同的冲突问题,因为您没有排序。因此,根据Perl版本的密钥顺序,您会得到随机密钥。既然OP没有说他们想要最早的,我想你也在做假设,尽管你的比我的好得多。但我认为问题还不清楚,问题是我需要获取小于第一个/最小散列键中出现的阈值的值,我认为这表明他想要最早的限定时间戳。如果你认为我的答案有问题,请在这里发表评论,因为讨论与你的答案无关。你能告诉我你是否有两个条目,如17值“1596561300”=>“19”,这等于2020-0804 22:45 00′=>19,例如‘1596561354’=>19’,相当于“2020-0804 22:45∶54′=>19,在这种情况下,你将考虑哪一个值?”i、 例如,“2020-08-04 22:45:00=>19”。您能告诉我您是否有两个条目,如17值“1596561300”=>19,这等于2020-0804 22:45 00′=>19,例如‘1596561354’=>19’,相当于“2020-0804 22:45∶54′=>19,在这种情况下,你将考虑哪一个值?”i、 e.,'2020-08-04 22:45:00=>19'。
Key : 2020-08-04 22:45:00 and Value :19