【问题标题】:Searching first level keys in a multidimensional hash Perl在多维哈希 Perl 中搜索第一级键
【发布时间】:2017-10-30 22:19:30
【问题描述】:

我在 Perl 中有一个多维散列的值。

它的结构是

$hash{$key}{$field}{$date} = $value;

鉴于我拥有正确的值和字段。

考虑到值本身是唯一的(与键具有 1-1 关系),搜索其键的最快过程是什么

编辑:

我添加了第三个级别,即日期。 并非所有日期都有一个值,但当它有值时,它会在所有日期之间共享。

为简化起见,如果有值,则为“A”,否则为空白。

问候, 因扎伊恩

【问题讨论】:

  • $hash{$_}{$field} eq $value and print "=> $_\n" for keys %hash; 如果您正在搜索一级密钥。
  • 可能需要print and last 那里。
  • 是的,还有带有块的常规 foreach(顺便说一句,可能有多个满足条件的第一级键)。
  • 这是否意味着我必须迭代每个可能的键并检查其值是否相同?
  • @InnZaayynn:如果这是您需要访问数据结构的方式,那么您的结构设计错误。

标签: perl multidimensional-array hash


【解决方案1】:

您的数据组织不适合进行快速搜索。您将不得不遍历整个哈希。如果您要执行多次搜索,最好生成“反向”哈希,这样您只需遍历整个哈希一次,而不是每次搜索一次。


如果您正在执行多个搜索,并且它们并非都针对同一字段,请按如下方式生成反向哈希:

my %key_by_field_and_value;
for my $key (keys(%hash)) {
   my $hash_for_key = $hash{$key};
   for my $field (keys(%$hash_for_key)) {
      my $hash_for_key_and_field = $hash_for_key->{$field};
      defined( my $date = get_any_one_key($hash_for_key_and_field) )
         or next;

      length( my $value = $hash_for_key_and_field->{$date} )
         or next;

      $key_by_field_and_value{$field}{$value} = $key;
   }
}

那么,搜索就变成了

my $field        = ...;
my $target_value = ...;

if (defined(
   my $target_key =
      do { no autovivification; $key_by_field_and_value{$field}{$target_value} }
)) {
   ...
}

如果您正在执行多个搜索,并且它们都针对同一个字段,请按如下方式生成反向哈希:

my $field = ...;

my %key_by_value;
for my $key (keys(%hash)) {
   my $hash_for_key = $hash{$key};
   defined( my $hash_for_key_and_field = $hash_for_key->{$field} )
      or next;

   defined( my $date = get_any_one_key($hash_for_key_and_field) )
      or next;

   length( my $value = $hash_for_key_and_field->{$date} )
      or next;

   $key_by_value{$value} = $key;
}

那么,搜索就变成了

my $target_value = ...;

if (defined( my $target_key = $key_by_value{$target_value} )) {
   ...
}

如果您只想搜索一次,则必须搜索整个哈希。

my $field        = ...;
my $target_value = ...;

my $target_key;
for my $key (keys(%hash)) {
   my $hash_for_key = $hash{$key};
   defined( my $hash_for_key_and_field = $hash_for_key->{$field} )
      or next;

   defined( my $date = get_any_one_key($hash_for_key_and_field) )
      or next;

   length( my $value = $hash_for_key_and_field->{$date} )
      or next;

   if ($value eq $target_value) {
      $target_key = $key;
      last;
   }
}

if (defined($target_key)) {
   ...
}

以上两种解决方案都使用my ($key) = keys(%$h);这个高效版本:

sub get_any_one_key {
   my ($h) = @_;
   my $key = each(%$h);
   keys(%$h);  # Reset iterator
   return $key;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-20
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-27
    • 2011-12-10
    • 2016-07-22
    相关资源
    最近更新 更多