向数组添加哈希

Wiz*_*ard 23 arrays perl hashtable multidimensional-array

我有一个像这样的数组,

@switch_ports = ()
Run Code Online (Sandbox Code Playgroud)

然后想要将这个哈希的50个实例添加到switch_ports数组中

%port = (data1 => 0, data2 => 0, changed => 0)
Run Code Online (Sandbox Code Playgroud)

但是,如果我将哈希值推送到数组中

push(@switch_ports, %port)
Run Code Online (Sandbox Code Playgroud)

但如果我打印@switch_ports,我只是看到了

data10data20changed0
Run Code Online (Sandbox Code Playgroud)

所以它似乎只是将它们添加到数组中,(加入它们)如果我尝试循环数组并打印键,它也会失败.

我想我会因为把头撞到桌子上而变得迟钝.

1 - 你可以在一个数组中存储哈希吗?

2 - 你有一系列哈希吗?

试图得到......

switchports
    0
        data1
        data2
        changed
    1
        data1
        ....
Run Code Online (Sandbox Code Playgroud)

从而

foreach $port (@switchport) {
    print $port['data1']
}
Run Code Online (Sandbox Code Playgroud)

将为数组中的所有哈希返回所有data1.

是的,我在Perl失败了

Dav*_* W. 40

在Perl中,数组和散列成员必须是单个值.在Perl 5.0之前,没有(简单的)方法可以做你想要的.

但是,在Perl 5中,您现在可以使用对哈希的引用.引用只是存储项目的内存位置.要获得引用,请在变量前添加反斜杠:

use feature qw(say);

my $foo = "bar";
say $foo;    #prints "bar"
say \$foo;   #prints SCALAR(0x7fad01029070) or something like that
Run Code Online (Sandbox Code Playgroud)

从而:

my @switch_ports = ();
my %port = ( data1 => 0, data2 => 0, changed => 0 );
my $port_ref = \%port;

push( @switch_ports, $port_ref );
Run Code Online (Sandbox Code Playgroud)

而且,您不必创建$port_ref:

my @switch_ports = ();
my %port = ( data1 => 0, data2 => 0, changed => 0 );

push( @switch_ports, \%port );
Run Code Online (Sandbox Code Playgroud)

要获得参考的实际值,只需将符号放回前面:

#Remember: This is a REFERENCE to the hash and not the hash itself
$port_ref = $switch_ports[0];
%port = %{$port_ref};      #Dereferences the reference $port_ref;

print "$port{data1}  $port{data2}  $port{changed}\n";
Run Code Online (Sandbox Code Playgroud)

另一个捷径:

%port = %{$port[0]};   #Dereference in a single step
print "$port{data1}  $port{data2}  $port{changed}\n";
Run Code Online (Sandbox Code Playgroud)

或者,甚至更短,在您进行时解除引用:

print ${$port[0]}{data1} . " " . ${$port[0]}{data2} . " " . ${$port[0]}{changed} . "\n";
Run Code Online (Sandbox Code Playgroud)

还有一点点语法甜味剂.它意味着相同,但更容易阅读:

print $port[0]->{data1} . " " . $port[0]->{data2} . " " . $port[0]->{changed} . "\n";
Run Code Online (Sandbox Code Playgroud)

看看Perldoc的perlreftutperlref.第一个是教程.

  • Perl 5.000于1994年10月17日发布.我认为到2011年,17年后,关于Perl4行为的免责声明已不再是非常必要的:) (11认同)
  • 你会认为情况就是这样.然而,有很多Perl教程仍然坚持古老的Perl 3.x语法:_如果它对爷爷来说已经足够好了,那对我来说已经足够了!_.我仍然看到人们使用`require"find.pl";`而不是`使用File :: Find;`和`chop`而不是`chomp`.甚至许多现代的_Learn Perl_书籍也从未被引用. (2认同)

TLP*_*TLP 10

当你尝试:

%port = (data1 => 0, data2 => 0, changed => 0);
push @switch_ports, %port;
Run Code Online (Sandbox Code Playgroud)

真正发生的是:

push @switch_ports, "data1", 0, "data2", 0, "changed", 0;
Run Code Online (Sandbox Code Playgroud)

因为在列表上下文中使用时,数组和哈希将自动分解为其元素.

当您想要创建50个哈希实例时,使用对其他人建议的现有哈希的引用并不是一个好主意,因为这只会创建对同一哈希的50个不同引用.由于显而易见的原因会崩溃和燃烧.

你需要的是:

push @array, { data1 => 0, data2 => 0, changed => 0 } for 1 .. 50;
Run Code Online (Sandbox Code Playgroud)

这将为数组添加50个唯一的匿名哈希值.大括号表示匿名散列的构造,并返回对它的标量引用.

ETA:您如何访问此数据的示例是错误的.

foreach $port (@switchport) {
    print $port['data1'];    # will use @port, not $port
}
Run Code Online (Sandbox Code Playgroud)

在标量变量上使用下标将尝试访问该命名空间中的数组,而不是标量.在Perl中,它是有效的有两个单独的参数$port@port.括号用于数组,而不是哈希.使用引用时,还需要使用箭头运算符:$port->{data1}.因此:

for my $port (@switchport) {
    print $port->{data1};
}
Run Code Online (Sandbox Code Playgroud)