Perl - 如何更新(和访问)存储在散列中存储的数组中的数组?

时间:2015-09-24 21:26:05

标签: arrays perl hash perl-data-structures

也许我已经把它变得比我需要的更复杂但是我正在尝试存储一个数组,其中包含Perl中哈希内部的数组。

即。哈希 - >数组 - >阵列

use strict;

my %DEVICE_INFORMATION = {}; #global hash

sub someFunction() {
    my $key = 'name';
    my @storage = ();

    #assume file was properly opened here for the foreach-loop
    foreach my $line (<DATA>) {
        if(conditional) {
            my @ports = ();

            $storage[0] = 'banana';
            $storage[1] = \@ports;
            $storage[2] = '0';

            $DEVICE_INFORMATION{$key} = \@storage;      
        }

        elsif(conditional) {
            push @{$DEVICE_INFORMATION{$key}[1]}, 5;
        }
    }#end foreach
} #end someFunction

这是我正在编写的代码的简化版本。我有一个子程序,我在主要调用。它解析一个非常专门设计的文件。该文件保证 if语句在后续elsif语句之前触发。

我认为elsif语句中的push调用无法正常工作 - 即5未存储在@port数组中,该数组应该存在于@storage数组中,当我将键散列到DEVICE_INFORMATION时应返回该数组。

在主要版本中,我尝试打印出@storage数组的每个元素,以检查事情是否顺利进行。

#main execution
&someFunction();

print $DEVICE_INFORMATION{'name'}[0];
print $DEVICE_INFORMATION{'name'}[1];
print $DEVICE_INFORMATION{'name'}[2];

这个输出结果是......香蕉ARRAY(blahblah)0

如果我将中间调用的print语句更改为:

print @{$DEVICE_INFORMATION{'name'}[1]};

或者:

print @{$DEVICE_INFORMATION{'name'}[1]}[0];

输出更改为banana [blankspace] 0

请告知我如何正确更新@ports数组,同时它存储在已经哈希到DEVICE_INFORMATION中的@storage数组中,然后我如何访问@ports的元素。非常感谢!

P.S。我为这篇文章的篇幅道歉。这是我关于stackoverflow的第一个问题。

2 个答案:

答案 0 :(得分:0)

我打算告诉您,Data::Dumper可以帮助您整理Perl数据结构,但Data::Dumper也可以告诉您有关第一个问题的信息:

以下是您在打开卷曲+密切卷曲(&#39; {}&#39;)到哈希时会发生什么:

use Data::Dumper ();

my %DEVICE_INFORMATION = {}; #global hash
print Dumper->Dump( [ \%DEVICE_INFORMATION ], [ '*DEVICE_INFORMATION ' ] );

这是输出:

%DEVICE_INFORMATION  = (
                         'HASH(0x3edd2c)' => undef
                       );

您所做的是将 stringified 哈希引用指定为后面的列表元素的键。 暗示

my %DEVICE_INFORMATION = {} => ();

因此,Perl为其指定了值 undef

分配哈希时,您可以分配一个列表。文字空哈希不是列表,它是哈希引用。您想要为哈希做什么 - 以及完全没有必要 - 是:

my %DEVICE_INFORMATION = ();

这是不必要的,因为完全相同

my %DEVICE_INFORMATION;

您正在声明哈希,并且该语句将其完全标识为哈希。并且Perl不会猜测你想要什么,所以它从一开始就是一个空的哈希。

最后,我建议使用Data::Dumper。如果您正确启动了哈希,并执行了以下操作:

my %DEVICE_INFORMATION; # = {}; #global hash    
my @ports = ( 1, 2, 3 );

# notice that I just skipped the interim structure of @storage
# and assigned it as a literal 
# * Perl has one of the best literal data structure languages out there.
$DEVICE_INFORMATION{name} = [ 'banana', \@ports, '0' ];
print Data::Dumper->Dump( 
      [ \%DEVICE_INFORMATION ]
    , [ '*DEVICE_INFORMATION' ] 
    );

你看到的是:

%DEVICE_INFORMATION  = (
                         'name' => [
                                     'banana',
                                     [
                                       1,
                                       2,
                                       3
                                     ],
                                     '0'
                                   ]
                       );

因此,您可以更好地了解它是如何存储的,以及您必须遵守的级别以及如何从中获取所需的信息。

顺便说一句,Data::Dumper提供100%可运行的Perl代码,并向您展示如何指定与文字相同的结构。有一点需要注意,你必须首先声明变量,使用strict(你应该总是使用它)。

答案 1 :(得分:-1)

您正确更新@ports 您的print语句以错误的方式访问$ storage [1](对@ports的引用) 您可以使用push中使用的语法。

print $DEVICE_INFORMATION{'name'}[0], ";",
      join( ':', @{$DEVICE_INFORMATION{'name'}[1]}), ";",
      $DEVICE_INFORMATION{'name'}[2], "\n";
print "Number of ports: ", scalar(@{$DEVICE_INFORMATION{'name'}[1]})),"\n";
print "First port: ", $DEVICE_INFORMATION{'name'}[1][0]//'', "\n";
# X//'' -> X or '' if X is undef