perl 向数组添加哈希

kknvjkwl  于 2022-11-15  发布在  Perl
关注(0)|答案(4)|浏览(267)

我有一个这样的数组:

@switch_ports = ()

然后希望将此哈希的50个示例添加到switch_ports数组。

%port = (data1 => 0, data2 => 0, changed => 0)

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

push(@switch_ports, %port)

然后我做print @switch_ports,我就看到:

data10data20changed0

所以它看起来只是把它们加到数组中,(加入它们)如果我尝试循环数组并打印键,它也会失败。
1.你能在数组中存储一个哈希值吗?
1.你能有一个散列数组吗?
我想知道:

switchports
    0
        data1
        data2
        changed
    1
        data1
        ....

因此:

foreach $port (@switchport) {
    print $port['data1']
}

将返回数组中所有散列的所有data1。

yhuiod9q

yhuiod9q1#

在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

因此:

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

push( @switch_ports, $port_ref );

而且,您不必创建$port_ref

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

push( @switch_ports, \%port );

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

#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";

另一条捷径:

%port = %{$port[0]};   #Dereference in a single step
print "$port{data1}  $port{data2}  $port{changed}\n";

或者,更简短地说,边走边解引用:

print ${$port[0]}{data1} . " " . ${$port[0]}{data2} . " " . ${$port[0]}{changed} . "\n";

还有一点语法上的甜味。意思是一样的,但更容易阅读:

print $port[0]->{data1} . " " . $port[0]->{data2} . " " . $port[0]->{changed} . "\n";

看看Perldoc的perlreftutperlref,第一个是教程。

t30tvxxf

t30tvxxf2#

当您尝试:

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

真正发生的是:

push @switch_ports, "data1", 0, "data2", 0, "changed", 0;

因为数组和散列在列表上下文中使用时会自动分解成它们的元素。
当你想创建一个哈希的50个示例时,像其他人建议的那样使用一个对现有哈希的引用不是一个好主意,因为这只会创建50个对同一个哈希的不同引用。
你需要的是这样的东西:

push @array, { data1 => 0, data2 => 0, changed => 0 } for 1 .. 50;

它将向数组中添加50个唯一的匿名哈希值。大括号表示匿名哈希值的构造,并返回对它的标量引用。
ETA:你关于如何访问这些数据的例子是错误的。

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

在标量变量上使用下标将试图访问该名称空间中的 array,而不是标量。在perl中,有两个单独的变量$port@port是有效的。括号用于数组,而不是散列。当使用引用时,还需要使用箭头操作符:$port->{data1}。因此:

for my $port (@switchport) {
    print $port->{data1};
}
fcg9iug3

fcg9iug33#

您可以在数组中存储 * 对 * 散列的引用:

push @switchport, \%port; # stores a reference to your existing hash

push @switchport, { %port }; # clones the hash so it can be updated separately

然后重复,比如说,

foreach my $port (@switchport) {
    print $port->{'data1'}; # or $$port{'data1'}
}

请参阅man perlref

rqenqsqc

rqenqsqc4#

为了简化那些使用这个问题来找到一个通用的方法-如在标题问题。Mysql主题:

my @my_hashes = ();
my @$rows = ... # Initialize. Mysql SELECT query results, for example.

if( @$rows ) {
    foreach $row ( @$rows ) { # Every row to hash, every hash to an array.
        push @my_hashes, { 
            id => $row->{ id }, 
            name => $row->{ name }, 
            value => $row->{ value }, 
        };
    }
}

循环并打印输出:

for my $i ( 0 .. $#my_hashes ) {
    print "$my_hashes[$i]{ id }\n ";
    print "$my_hashes[$i]{ name }\n ";
    print "$my_hashes[$i]{ value }\n ";
}

for my $i ( 0 .. $#my_hashes ) {
for my $type ( keys %{ $my_hashes[$i] } ) {
     print "$type=$my_hashes[$i]{$type} ";
}

}

相关问题