我有一个像这样的数组,
@switch_ports = ()
然后想要将此哈希的50个实例添加到switch_ports数组
%port = (data1 => 0, data2 => 0, changed => 0)
但是,如果我将哈希值推送到数组
push(@switch_ports, %port)
但如果我打印@switch_ports 我刚看到
data10data20changed0
所以它似乎只是将它们添加到数组中,(加入它们) 如果我尝试循环数组并打印键,它也会失败。
我想我会因为把头撞到桌子上而变得迟钝。
1 - 你能在数组中存储哈希吗?
2 - 你能有一系列哈希吗?
试图获得......
switchports
0
data1
data2
changed
1
data1
....
从而
foreach $port (@switchport) {
print $port['data1']
}
将返回数组中所有哈希值的所有data1。
是的,我在Perl失败了
答案 0 :(得分:38)
在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的perlreftut和perlref。第一个是教程。
答案 1 :(得分:9)
当你尝试:
%port = (data1 => 0, data2 => 0, changed => 0);
push @switch_ports, %port;
真正发生的是:
push @switch_ports, "data1", 0, "data2", 0, "changed", 0;
因为在列表上下文中使用数组和哈希值automatically break into their elements。
当你想要创建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
}
在标量变量上使用下标将尝试访问该命名空间中的数组,而不是标量。在perl中,有两个单独的变量$port
和@port
是有效的。括号用于数组,而不是哈希。使用引用时,还需要使用箭头运算符:$port->{data1}
。因此:
for my $port (@switchport) {
print $port->{data1};
}
答案 2 :(得分:4)
您可以在数组中存储对哈希的引用:
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
。
答案 3 :(得分:3)
简化使用此问题的人找到一般方法 - 如标题问题。 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} ";
}
}