Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl创建散列引用并一次遍历每个分支中的一个元素_Perl_Loops_Hash_For Loop_Hash Reference - Fatal编程技术网

Perl创建散列引用并一次遍历每个分支中的一个元素

Perl创建散列引用并一次遍历每个分支中的一个元素,perl,loops,hash,for-loop,hash-reference,Perl,Loops,Hash,For Loop,Hash Reference,作为一个初学者,我有一个我认为相当复杂的问题,我希望有人能帮我解决 我有以下文本文件(已删除选项卡) FILE1.txt Dog Big Dog Medium Dog Small Rabbit Huge Rabbit Tiny Rabbit Middle Donkey Massive Donkey Little Donkey Gigantic 我需要将

作为一个初学者,我有一个我认为相当复杂的问题,我希望有人能帮我解决

我有以下文本文件(已删除选项卡)

FILE1.txt

Dog     Big     
Dog     Medium     
Dog     Small     
Rabbit     Huge     
Rabbit     Tiny     
Rabbit     Middle    
Donkey     Massive    
Donkey     Little   
Donkey     Gigantic
我需要将FILE1.txt读入一个散列引用,以获得如下内容。。。(使用数据::转储程序)

我遇到的问题:

然后我需要一次一个循环遍历散列引用的每个分支,我将使用散列引用中的值来检查它是否与我的关键字匹配,如果匹配,它将返回它对应的键。。。。例如

我需要它做什么:

my $keyword == "Little";

Dog->Big 
if 'Big' matches my keyword then return $found = Dog
else go to the next branch
Rabbit->Huge
if 'Huge' matches my keyword then return $found = Rabbit
else go to the next branch
Donkey->Massive
if 'Massive' matches my keyword then return $found = Donkey
else go to the next branch (which is Dog again, but the second element this time)
Dog->Medium
if 'Medium' matches my keyword then return $found = Dog
else go to the next branch
Rabbit->Tiny
if 'Tiny' matches my keyword then return $found = Rabbit
else go the the next branch
Donkey->Little
if 'Little' matches my keyword then return $found = Donkey
。。。。。依此类推,直到找到关键字或到达哈希引用的结尾

这正是我试图实现的目标,但我不知道如何实现这一目标,也不知道散列引用是否是实现这一目标的最佳方法,或者是否可以使用散列/散列引用来实现这一目标?

my $keyword == "Little";

Dog->Big 
if 'Big' matches my keyword then return $found = Dog
else go to the next branch
Rabbit->Huge
if 'Huge' matches my keyword then return $found = Rabbit
else go to the next branch
Donkey->Massive
if 'Massive' matches my keyword then return $found = Donkey
else go to the next branch (which is Dog again, but the second element this time)
Dog->Medium
if 'Medium' matches my keyword then return $found = Dog
else go to the next branch
Rabbit->Tiny
if 'Tiny' matches my keyword then return $found = Rabbit
else go the the next branch
Donkey->Little
if 'Little' matches my keyword then return $found = Donkey

非常感谢您在这方面的帮助,感谢您批评我自己的答案:搜索部分的结构可能会更好。甚至使用有序散列也可能毫无意义,因为搜索是通过线性列表进行的。也许它应该是一个数组的数组

   use strict;
    use warnings;
    use Tie::IxHash;
    #open file
    open(my $fh,"ani.txt") ||die $!;

    #make an ordered hash
    tie my %sizes, 'Tie::IxHash';


    #read file into hash of arrays
    while(<$fh>) {
       (my $animal,my $size)=split(/\s+/);
       if (!exists($sizes{$animal})) {
           $sizes{$animal} = [$size];
       } else { 
           push @{$sizes{$animal}},$size;
       }
    }

    my $keyword="Little";
    my $running=1;
    my $depth=0;
    while( $running ) {
      $running = 0;
      for my $search (keys %sizes) {
          next if ($depth > @{$sizes{$search}});
          $running = 1;
          if ($keyword eq $sizes{$search}[$depth]) {
              print "FOUND!!!!!! $search $depth";
              exit(0);
          }
      }
      $depth++;
    }
使用严格;
使用警告;
使用Tie::ixash;
#打开文件
打开(my$fh,“ani.txt”)| | die$!;
#做一个有序的散列
绑定我的%Size,“绑定::IxHash”;
#将文件读入数组的散列
while(){
(我的$animal,我的$size)=拆分(/\s+/);
如果(!存在($size{$animal})){
$size{$animal}=[$size];
}否则{
推送{$size{$animal}},$size;
}
}
我的$keyword=“Little”;
我的$running=1;
我的$depth=0;
同时($运行){
$running=0;
用于我的$搜索(关键字%sizes){
下一个if($depth>@{$size{$search}});
$running=1;
if($keyword eq$size{$search}[$depth]){
打印“找到!!!!!!!$search$depth”;
出口(0);
}
}
$depth++;
}
下面是所述问题的另一种解决方案。为了解决实际问题,给定一个散列,除了每个动物的第一个“大小”键之外,不需要存储任何东西

这个散列可以被三位一体地用来查找动物

use strict;
use warnings;
open(my $fh,"ani.txt") ||die $!;

my %animals;

#read file into hash
while(<$fh>) {
   (my $animal,my $size)=split(/\s+/);
   #only add the animal the first time the size is found
   if (!exists($animals{$size})) {
       $animals{$size} = $animal;
   } 
}

my $keyword="Little";
print "animal is ", $animals{$keyword};
使用严格;
使用警告;
打开(my$fh,“ani.txt”)| | die$!;
我的%是动物;
#将文件读入散列
while(){
(我的$animal,我的$size)=拆分(/\s+/);
#仅在第一次找到尺寸时添加动物
如果(!存在($animals{$size})){
$animals{$size}=$animal;
} 
}
我的$keyword=“Little”;
打印“animal is”,$animals{$keyword};

选择合适的数据结构通常是解决方案的关键步骤,但首先您应该定义您要实现的目标。总体目标是什么?例如,我有这个数据文件,在我的应用程序/程序中,我需要经常询问这些信息。问正确的问题是至关重要的,因为例如,若你们不需要经常问关键词,那个么创建哈希就毫无意义

 perl -anE'say $F[0] if $F[1] eq "Little"' FILE1.txt
是的,就是这么简单。查看
perlrun
手册页中的交换机及其含义,以及如何在更大的应用程序中执行相同的操作

如果你需要经常问这个问题,你应该以有助于你的方式来安排你的数据,而不是以你不得不面对的方式

use strict;
use warnings;
use feature qw(say);
use autodie;

open my $f, '<', 'FILE1.txt';
my %h;
while(<$f>) {
    chomp;
    my ($animal, $keyword) = split' ';
    $h{$keyword} = $animal unless exists $h{$keyword};
}

close $f;

for my $keyword (qw(Little Awkward Small Tiny)) {
    say $h{$keyword} ? "$keyword $h{$keyword}" : "keyword $keyword not found";
}
使用严格;
使用警告;
使用特征qw(例如);
使用自动模具;

打开我的$f,'如果你要按形容词(小、大、小等)查找,为什么不用它们作为键来构建哈希?@TLP-但在结尾我真正需要的是与形容词相关联的狗、兔子或驴子部分,谢谢。我知道这一点。您知道可以将值“Dog”存储在键“Little”下,就像将值“Little”存储在键“Dog”下一样简单,对吗?1)您的“Data::Dumper”哈希示例不正确。您在每个键下显示一个列表,而不是散列。2) 构建2个散列怎么样。一个来自animal->[形容词列表]和一个来自Animable->animal@mob:不,要求是为每个顶级键执行所有第一个元素,然后执行所有第二个元素。子散列似乎需要排序,所以应该是数组,而不是散列。
open my $f, '<', 'FILE1.txt';
my %h;
while (<$f>) {
    chomp;
    my ( $animal, $keyword ) = split ' ';
    push @{ $h{$animal} }, $keyword;
}

close $f;

KEYWORD:
for my $keyword (qw(Little Awkward Small Tiny)) {
    for my $animal (keys %h) {
        for my $k (@{$h{$animal}}) {
            if($k eq $keyword) {
                say "$keyword $animal";
                next KEYWORD;
            }
        }
    }
    say "keyword $keyword not found";
}