Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
405 views
in Technique[技术] by (71.8m points)

perl - How to fetch key of a hash through values in Hash of Arrays

Below is the small code snippet i have created using Hash Key and Hash Value which is an array. And my input is Hash value (Array in this case) , i have to search for all the arrays in $ENV hash and fetch the hash key

Example if i search for m3d1 , the output should be TEST3

  use strict;
  use warnings;
  use Data::Dumper;
  my %ENV;
  
  $ENV{"TEST3"}=["m3d1","m3d2"] ;
  $ENV{"TEST4"}=["m4d1","m4d2"] ;
  $ENV{"TEST5"}=["m5d1","m5d2"] ;
  $ENV{"TEST6"}=["m6d1","m6d2"] ;
  print Dumper @keys;
  print Dumper @values;

Is it possible , or is there a better design ?

question from:https://stackoverflow.com/questions/66058658/how-to-fetch-key-of-a-hash-through-values-in-hash-of-arrays

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Of course it's possible. We can visit every value in the data structure until we find the one that matches.

You didn't say what the strings represent, to I'm going to call TEST3 a group, and I'm going to call m3d1 a host. The following snippets don't assume a host is preset in only one of group.

my @groups;
for my $group (keys(%ENV)) {
   for my $host (@{ $ENV{$group} }) {
      if ($host eq $target_host) {
         push @groups, $group;
      }
   }
}

die("Not found
") if !@groups;

say for @groups;

But this isn't efficient. If you were planning on doing many lookups, this would be slow.

Let's start by turning the structure inside out.

my %groups_by_host;
for my $group (keys(%ENV)) {
   for my $host (@{ $ENV{$group} }) {
      push @{ $groups_by_host{$host} }, $group;
   }
}

The above produces

my %groups_by_host = (
   m3d1 => [ "TEST3" ],
   m3d2 => [ "TEST3" ],
   m4d1 => [ "TEST4" ],
   m4d2 => [ "TEST4" ],
   m5d1 => [ "TEST5" ],
   m5d2 => [ "TEST5" ],
   m6d1 => [ "TEST6" ],
   m6d2 => [ "TEST6" ],
);

Then, searching becomes instantaneous.

my $groups = $groups_by_host{$target_host}
   or die("Not found
");

say for @$groups;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...