插入和迭代数组的散列
Inserting and iterating over hash of arrays
我有以下输入数据
Country1:operator1
Country1:operator2
Country1:operator3
Country2:operator1
Country2:operator2
Country2:operator3
我想将这些数据插入到散列 %INFO
中,这样每个键都对应一个 "operators" 的数组,所以我可以按以下方式迭代
foreach $i ( keys %INFO ) {
foreach $operator ( $INFO{$i} ) {
print " $i ---> $operator \n";
}
}
这是我自己的解决方案,但效果不佳
open($fh, "$info_file");
while (my $row = <$fh>) {
chomp $row;
@tokens = split(":",$row);
$name = $tokens[0];
$operator = $tokens[2];
if ($name =~ /^[A-Z]/) {
if ( exists $INFO{$name} ) {
$ptr = $INFO{$name};
push(@ptr, $operator);
}
else {
@array = ( "$operator" );
$INFO{$name} = [ @array ];
}
}
}
close($f);
恐怕你过于复杂了。
open my $fh, '<', $info_file or die "Can't open '$info_file': $!";
my %info;
while (<$fh>) {
next unless /^[A-Z]/;
chomp;
my ($name, $operator) = split /:/;
push @{ $info{$name} }, $operator;
}
并访问它:
foreach my $i (keys %info) {
foreach my $op (@{ $info{$i} }) {
say "$i ----> $op";
}
}
如果您将散列值视为数组引用,那么 Perl 会将其设为数组引用。
有关详细信息,请参阅 Perl Data Structures Cookbook。
好的,首先这段代码有很多错误,使用open的三种输入形式并且默认不引用变量,Perl知道什么时候应该是字符串。所以 open($fh,"$info_file");
应该是 open($fh, '<', $info_file);
第二次分割默认不return分隔符所以$operator = $tokens[2];
应该是$operator = $tokens[1];
第三,为什么要忽略文件中不以 A 到 Z 开头的国家/地区?
第四次使用自动激活所以整个if else
块可以被push @{$INFO{$name}}, $operator
替换
第五,$ptr
和 @ptr
是单独的变量,将数组引用分配给 $ptr
不会使其在 @ptr
中可用,而且 $INFO{$name}
正在使用引用 $INFO{$name}
是什么,在你的情况下它已经是一个数组引用所以你在 $ptr
中得到一个数组引用的引用 如果你保持这段代码。
第六次赋值给@array是多余的else子句中的两行应该写成$INFO{$name} = [ $operator ];
通过所有这些更改,您得到
open($fh, '<', "$info_file");
while (my $row = <$fh>) {
chomp $row;
my @tokens = split(":",$row);
$name = $tokens[0];
$operator = $tokens[1];
if ($name =~ /^[A-Z]/) {
push @{$INFO{$name}}, $operator;
}
}
close($f);
你已经很接近了,但不需要显式使用引用或将哈希值初始化为空数组
这就是您所需要的
use strict;
use warnings 'all';
open my $fh, '<', $info_file or die $!;
my %info;
while ( <$fh> ) {
chomp;
my ($name, $operator) = split /:/;
push @{ $info{$name} }, $operator if $name =~ /^[A-Z]/;
}
我有以下输入数据
Country1:operator1
Country1:operator2
Country1:operator3
Country2:operator1
Country2:operator2
Country2:operator3
我想将这些数据插入到散列 %INFO
中,这样每个键都对应一个 "operators" 的数组,所以我可以按以下方式迭代
foreach $i ( keys %INFO ) {
foreach $operator ( $INFO{$i} ) {
print " $i ---> $operator \n";
}
}
这是我自己的解决方案,但效果不佳
open($fh, "$info_file");
while (my $row = <$fh>) {
chomp $row;
@tokens = split(":",$row);
$name = $tokens[0];
$operator = $tokens[2];
if ($name =~ /^[A-Z]/) {
if ( exists $INFO{$name} ) {
$ptr = $INFO{$name};
push(@ptr, $operator);
}
else {
@array = ( "$operator" );
$INFO{$name} = [ @array ];
}
}
}
close($f);
恐怕你过于复杂了。
open my $fh, '<', $info_file or die "Can't open '$info_file': $!";
my %info;
while (<$fh>) {
next unless /^[A-Z]/;
chomp;
my ($name, $operator) = split /:/;
push @{ $info{$name} }, $operator;
}
并访问它:
foreach my $i (keys %info) {
foreach my $op (@{ $info{$i} }) {
say "$i ----> $op";
}
}
如果您将散列值视为数组引用,那么 Perl 会将其设为数组引用。
有关详细信息,请参阅 Perl Data Structures Cookbook。
好的,首先这段代码有很多错误,使用open的三种输入形式并且默认不引用变量,Perl知道什么时候应该是字符串。所以 open($fh,"$info_file");
应该是 open($fh, '<', $info_file);
第二次分割默认不return分隔符所以$operator = $tokens[2];
应该是$operator = $tokens[1];
第三,为什么要忽略文件中不以 A 到 Z 开头的国家/地区?
第四次使用自动激活所以整个if else
块可以被push @{$INFO{$name}}, $operator
第五,$ptr
和 @ptr
是单独的变量,将数组引用分配给 $ptr
不会使其在 @ptr
中可用,而且 $INFO{$name}
正在使用引用 $INFO{$name}
是什么,在你的情况下它已经是一个数组引用所以你在 $ptr
中得到一个数组引用的引用 如果你保持这段代码。
第六次赋值给@array是多余的else子句中的两行应该写成$INFO{$name} = [ $operator ];
通过所有这些更改,您得到
open($fh, '<', "$info_file");
while (my $row = <$fh>) {
chomp $row;
my @tokens = split(":",$row);
$name = $tokens[0];
$operator = $tokens[1];
if ($name =~ /^[A-Z]/) {
push @{$INFO{$name}}, $operator;
}
}
close($f);
你已经很接近了,但不需要显式使用引用或将哈希值初始化为空数组
这就是您所需要的
use strict;
use warnings 'all';
open my $fh, '<', $info_file or die $!;
my %info;
while ( <$fh> ) {
chomp;
my ($name, $operator) = split /:/;
push @{ $info{$name} }, $operator if $name =~ /^[A-Z]/;
}