在Perl中推入hash的结尾

时间:2012-07-20 13:25:38

标签: perl data-structures hash push

所以我试图用以下代码做的是推送一个字符串,让我们在散列中的每个键的末尾说“this string”。我完全不知道如何做到这一点。这是我的代码:

use warnings;
use strict;
use File::Find;

my @name;
my $filename;
my $line;
my @severity = ();
my @files;
my @info = ();
my $key;
my %hoa;
my $xmlfile;
my $comment;
my @comments;

open( OUTPUT, "> $ARGV[0]" );
my $dir = 'c:/programs/TEST/Test';

while ( defined( $input = glob( $dir . "\\*.txt" ) ) ) {
    open( INPUT, "< $input" );

    while (<INPUT>) {
        chomp;

        if (/File/) {
            my @line = split /:/;
            $key = $line[1];
            push @{ $hoa{$key} }, "Filename\n";
        }

        if ( /XML/ ... /File/ ) {
            $xmlfile = $1;
            push @{ $hoa{$key} }, "XML file is $xmlfile\n";

        }
        if (/Important/) {
            push @{ $hoa{$key} }, "Severity is $_\n";
        }
        if (/^\D/) {
            next if /Important/;
            push @{ $hoa{$key} }, "Given comment is $_\n";
        }
        push @{ $hoa{$key} }, "this string\n";
    }

}

foreach my $k ( keys %hoa ) {
    my @list = @{ $hoa{$k} };
    foreach my $l (@list) {
        print OUTPUT $l, "\n";
    }
}

}
close INPUT;
close OUTPUT;

我有“这个字符串”是我试图将该字符串推送到数组末尾的地方。然而,最终发生的事情是它最终打印了“这个字符串”三次,而不是像我想要的那样在每个键的末尾打印。当我试图把它放在while()循环之外时,它说$ key的值没有被初始化。所以,请帮忙吗?如果您需要澄清我的要求,请告诉我。谢谢!

5 个答案:

答案 0 :(得分:3)

没有冒犯,但是这段代码中有很多问题,我甚至不知道从哪里开始......

首先,Perl中不需要'初始化块'(此脚本开头的所有这些my $something; my @somethings行)。事实上,它不仅仅是“多余的” - 它实际上令人困惑:每次遇到一个新变量时我都必须来回移动我的焦点来检查它的类型。此外,即使所有这些$input var仍未被声明为本地;它或者在评论中缺失,或者给出的代码有遗漏。

其次,为什么宣布你打算使用File :: Find(好) - 但是根本不使用它?它可以大大简化所有while(glob) { while(<FH>) { ... } }例程。

第三,我不确定为什么只有当行读取与/ File /匹配时才向$key分配内容,但在其他所有情况下都将其值用作键。这是尝试读取按部分组织的文件吗?然后可以通过slurp / splitting或本地化$/变量来更简单地完成...

无论如何,重点是如果扫描的文件的第一行与/File/不匹配,则使用前一个(即,来自前一个文件!)的值 - 我不太确定它的目的。如果第一个文件的第一行不是/File/ - 匹配,那么一个空字符串被用作键 - 再次,它闻起来像一个bug ...

您能否详细描述一下您的任务?给出一些测试输入/输出结果,或许......继续执行简短任务,组织代码进行处理会很棒。

答案 1 :(得分:3)

你的程序设计不合理,打破了很多良好做法规则。而不是全部枚举它们,这是一个具有更好结构的等效程序。

我想知道您是否知道{em>所有的if语句都会被测试并可能被执行?也许您需要使用elsif

除了在使用$ key时未定义$ key的可能性之外,您还将$xmlfile设置为$1永远将被定义为没有捕获任何正则表达式。

无法从你的代码中判断出你想要做什么,所以只有当你向我们展示你的输出,输入并说出如何从另一个中推导出来时,我们才能帮助你。

use strict;
use warnings;

use File::Find;

my ($outfile) = @ARGV;

my $dir = 'c:/programs/TEST/Test';

my %hoa;
my $key;

while (my $input = glob "$dir/*.txt") {

  open my $in, '<', $input or die $!;

  while (<$in>) {

    chomp;

    if (/File/) {
      my $key = (split /:/)[1];
      push @{ $hoa{$key} }, "Filename\n";
    }

    if (/XML/ ... /File/) {
      my $xmlfile = $1;
      push @{ $hoa{$key} }, "XML file is $xmlfile\n";
    }

    if (/Important/) {
      push @{ $hoa{$key} }, "Severity is $_\n";
    }

    if (/^\D/) {
      next if /Important/;
      push @{ $hoa{$key} }, "Given comment is $_\n";
    }

    push @{ $hoa{$key} }, "this string\n";
  }

  close $in;
}

open my $out, '>', $outfile or die $!;

foreach my $k (keys %hoa) {
  foreach my $l (@{ $hoa{$k} }) {
    print $out $l, "\n";
  }
}

close $out;

答案 2 :(得分:1)

我怀疑基于你的代码,每次循环都没有调用设置$ key的行,并且你不会触发任何其他if语句。

这会将“this string”追加到数组的末尾。基于你在数组的末尾得到3个“this strings”,我怀疑两行不通过if(/ FILE /)或任何其他if语句。这将使$ key值保持不变,最后,您将使用$ key的最后一个值设置时将“this string”追加到数组中。

答案 3 :(得分:1)

这会将字符串"this string"附加到散列%hoa的每个元素,这些元素是数组引用:

for (values(%hoa)) { push @{$_}, "this string"; }

将它放在while循环之外,然后在%hoa的每个元素的末尾打印“this string”。

它将自动生成数组引用,它会找到undef元素。如果它不能将元素作为数组取消引用,它也会阻塞,并且如果它找到一个简单的标量并且在严格下运行,它将通过符号引用来操作数组。

my %autoviv = ( a => ['foo'], b => undef );
push @$_, "PUSH" for values %autoviv;        # ( a => ['foo', 'PUSH'], b => ['PUSH'] )

my %fatal = ( a => {} );
push @$_, "PUSH" for values %fatal;          # FATAL:  "Not an ARRAY reference at..."

my %dangerous = (a => "foo");
push @$_, "PUSH" for values %dangerous;      # Yikes!  @foo is now ("PUSH")

use strict;
my %kablam = (a => "foo");
push @$_, "PUSH" for values %kablam;         # "Can't use string ("foo") as an ARRAY ref ..."

答案 4 :(得分:0)

据我了解,使用map命令遍历散列以修改其密钥。一个例子:

编辑:我编辑过,因为我意识到map命令可以分配给同一个哈希。无需创建新的。

#!/usr/bin/perl

use warnings;
use strict;
use Data::Dumper;

my %hash = qw|
    key1    value1
    key2    value2
    key3    value3
|;

my %hash = map { $_ . "this string" => $hash{ $_ } } keys %hash;

print Dump \%hash;

像以下一样运行:

perl script.pl

使用以下输出:

$VAR1 = {
          'key3this string' => 'value3',
          'key2this string' => 'value2',
          'key1this string' => 'value1'
        };