1

在这段代码中,我正在检查某个键是否存在。在这里,我正在检查键“Uri”是否存在。我得到的输出为“3”。

use strict; 
use warnings;

my %Names = ( 
    Martha  =>2, 
    Vivek   =>9, 
    Jason   =>6, 
    Socrates=>7, 
    Uri     =>3, 
    Nitin   =>1, 
    Plato   =>0, 
); 

if (exists $Names{Uri} ) {
    print "$Names{Uri}\n";
}
foreach my $name (sort {$Names{$a} cmp $Names{$b}} keys %Names) 
{ 
    print $name, $Names{$name}."\n";
} 

输出

3
Plato    0
Nitin    1
Martha   2
Uri      3
Jason    6
Socrates 7
Vivek    9

但是,我希望在该键之前出现前一个键值。例如:

  1. 如果我搜索键“Uri”输出应该是“2”
  2. 如果我搜索键“Vivek”输出应该是“7”
  3. 如果我搜索关键“柏拉图”输出应该是“0”

有谁知道该怎么做?

4

2 回答 2

2

创建一个哈希的排序数组,然后在数组中搜索以获取刚好低于搜索键值的值。

use strict; 
use warnings;

my %Names = ( 
    Martha  =>2, 
    Vivek   =>9, 
    Jason   =>6, 
    Socrates=>7, 
    Uri     =>3, 
    Nitin   =>1, 
    Plato   =>0, 
); 

my @vals = sort {$a <=> $b} values %Names;

get_prev('Uri');
get_prev('Vivek');
get_prev('Plato');

sub get_prev {
    my $k = shift;
    if (exists $Names{$k}) {
        for (@vals) {
            if ($Names{$k} == $vals[$_]) {
                my $idx = ($_ == 0) ? 0 : $_ - 1;
                print $vals[$idx], "\n";
                last;
            }
        }
    }
}

印刷:

2
7
0
于 2021-02-16T21:20:07.490 回答
1

如果要全部打印:

my $prev;
for my $name (
   sort { $Names{$a} <=> $Names{$b} }    # Note to use of <=> for numerical comparisons.
      keys(%Names)
) {
   say "$name $Names{$prev}" if $prev;
   $prev = $name;
} 

同样,只打印一个

my $find = 'Uri';

my $prev;
for my $name (
   sort { $Names{$a} <=> $Names{$b} }
      keys(%Names)
) {
   if ($name eq $find) {
      say "$name $Names{$prev}" if $prev;
      last;
   }

   $prev = $name;
}

上面的帽子将是一种执行多次查找的昂贵方式。为此,我们将构建从名称到先前名称的映射。

my %prev_name_lkup;
my $prev;
for my $name (
   sort { $Names{$a} <=> $Names{$b} }
      keys(%Names)
) {
   $prev_name_lkup{$name} = $prev if $prev;
   $prev = $name;
} 

这也可以按如下方式完成:

my @sorted_names =
   sort { $Names{$a} <=> $Names{$b} }
      keys(%Names);

my %prev_name_lkup =
   map { $sorted_names[$_-1] => $sorted_names[$_] }
      1..$#sorted_names;

无论哪种方式,查找将如下所示:

say "Uri $Names{$prev_name_lkup{Uri}}";
于 2021-02-17T05:49:48.120 回答