Perl哈希值为数组

时间:2017-05-31 16:12:58

标签: perl perl-hash

我有一个如下输入文件:

start
f1="apple"
f2="banana"
f3="berry"
end
start
f1="guava"
f2="banana"
f3="berry"
end
start
f1="apple"
f2="cucumber"
f3="orance"
end

我打算创建一个值为数组的哈希。

所有标签都在一个临时数组中,并且在标签之间有一个字段f1,其值将是散列的关键字。

从开始到结束它将存储在临时数组中,一旦到达结束,数组将被推送为hash的值,其中key为最新字符串f1=后面的值

我编写了以下代码,但它不起作用。

有人可以在此建议任何更正吗?

#!/usr/bin/perl -w

use strict;

use Data::Dumper;

open( FILE, "<", "temp2" );

my %FILEDATA;
my @tmp   = ();
my $fruit = "";

while ( <FILE> ) {

    chomp( $_ );
    push @tmp, $_;

    my @linefields = split( '=', $_ );

    if ( $linefields[0] =~ /f1/ ) {
        $fruit = $linefields[1];
    }

    if ( $_ =~ /end/ ) {

        if ( $fruit eq "apple" ) {

            if ( exists $FILEDATA{"apple"} ) {
                push( @{ $FILEDATA{"apple"} }, @tmp );
            }
            else {
                $FILEDATA{"apple"} = @tmp;
            }
        }
        elsif ( $fruit eq "guava" ) {

            if ( exists $FILEDATA{"guava"} ) {
                push( @{ $FILEDATA{"guava"} }, @tmp );
            }
            else {
                $FILEDATA{"guava"} = @tmp;
            }

        }

        undef @tmp;
    }
}

print Dumper( \%FILEDATA );

2 个答案:

答案 0 :(得分:1)

我假设这是家庭作业

以下是一些指南

  • $_是许多Perl运算符的默认参数。特别是,chomp( $_ )可以写为chompsplit( '=', $_ )应为split /=/if ( $_ =~ /end/ ) { ... }可以为if ( /end/ )

  • 无需测试$fruit的值。如果它的值是您想要的密钥,那么您应该使用$FILEDATA{$fruit}

  • $FILEDATA{"apple"} = @tmp$FILEDATA{"apple"}设置为@tmp元素的数量。您需要使用$FILEDATA{"apple"} = \@tmp

  • 将其设置为对数组的引用
  • 在使用push之前,无需检查哈希值或数组元素是否存在。如果您只是push @{ $FILEDATA{apple} }, 'ff',那么将创建数组

  • if ( $linefields[0] =~ /f1/ )测试$linefields[0] 是否包含字符串f1。要测试您想要的平等if ( $linefields[0] eq 'f1' )

  • 您不应使用undef @data@data = undef清空数组或哈希值。正确的方法是@data = ()。要清空标量,请使用$val = undef

以下是代码的外观

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

open FILE, "<", "fruit.txt";

my %data;
my @tmp;
my $fruit;

while ( <FILE> ) {

    chomp;
    push @tmp, $_;

    my @fields = split /=/;

    if ( $fields[0] eq 'f1' ) {
        $fruit = $fields[1];
    }

    if ( /end/ ) {
        push @{ $data{$fruit} }, [ @tmp ];
        @tmp = ();
    }
}

print Dumper( \%data );

输出

$VAR1 = {
          '"guava"' => [
                         [
                           'start',
                           'f1="guava"',
                           'f2="banana"',
                           'f3="berry"',
                           'end'
                         ]
                       ],
          '"apple"' => [
                         [
                           'start',
                           'f1="apple"',
                           'f2="banana"',
                           'f3="berry"',
                           'end'
                         ],
                         [
                           'start',
                           'f1="apple"',
                           'f2="cucumber"',
                           'f3="orance"',
                           'end'
                         ]
                       ]
        };

这就是我写它的方式

#!/usr/bin/perl

use strict;
use warnings;
use autodie;

use Data::Dumper;

my $file = 'fruit.txt';

open my $fh, '<', $file
    or die qq{Unable to open "$file": $!};

my ( %data, @block, $fruit );

while ( my $line = <$fh> ) {

    chomp $line;

    push @block, $line if @block or $line eq 'start';

    $fruit = $1 if $line =~ /^f1="(\w+)"/;

    if ( $line eq 'end' ) {
        push @{ $data{$fruit} }, [ @block ];
        @block = ();
        $fruit = undef;
    }
}

print Dumper \%data;

请注意,您不应使用undef @data@data = undef清空数组或哈希值。正确的方法是@data = ()

答案 1 :(得分:-1)

试试此代码

my $file = 'fruits.txt';
my %hash;


open (my $fh, '<', $file) or die "Could not open $!";
while(my $line = <$fh>) {
  next if $line =~ /start/;
  next if $line =~ /end/;

  if ($line =~ /f1/) {
     my ($key, $val) = split /=/, $line;
     push @{$hash{$key}}, $val;
   }

   if ($line =~ /f2/) {
    my ($key, $val) = split /=/, $line;
    push @{$hash{$key}}, $val;
   }

   if ($line =~ /f3/) {
    my ($key, $val) = split /=/, $line;
    push @{$hash{$key}}, $val;
   }

}

print Dumper(\%hash);