Arrays Perl:正确打印数组数组(取消引用)
各位僧侣 我仍在思考如何正确地取消引用。(我在发帖之前读过类似的帖子,但不幸的是我对这个概念还是有点模糊。) 我有以下数组,它在内部由两个数组组成。(顺便说一句,我使用的是严格和警告的pragmas。) 其中:Arrays Perl:正确打印数组数组(取消引用),arrays,for-loop,dereference,perl,Arrays,For Loop,Dereference,Perl,各位僧侣 我仍在思考如何正确地取消引用。(我在发帖之前读过类似的帖子,但不幸的是我对这个概念还是有点模糊。) 我有以下数组,它在内部由两个数组组成。(顺便说一句,我使用的是严格和警告的pragmas。) 其中: @a1 = ( "1MB", "2MB", ... ) 和 @a1和@a2都是包含51行的数组。所以,我把它们填充到我的第二个数组中 my @b; push (@b, [ @a1, @a2 ]); 但是,当我尝试打印@b的结果时: sub newl { print "\n"; pri
@a1 = ( "1MB", "2MB", ... )
和
@a1和@a2都是包含51行的数组。所以,我把它们填充到我的第二个数组中
my @b;
push (@b, [ @a1, @a2 ]);
但是,当我尝试打印@b的结果时:
sub newl { print "\n"; print "\n"; }
my $an1; my @an1;
$an1 = $#a1;
@an1 = ( 0, 1..$an1 );
for my $i (@an1) { print @b[$i]; &newl; }
我看到对数组的引用:
ARRAY(0x81c0a10)
.
ARRAY(0x81c0a50)
.
.
.
如何正确打印此阵列?我知道我需要取消对数组的引用,但我不知道如何进行。我尝试填充数组,如下所示:
push (@b, [ \@a1, \@a2 ]);
这会产生相同的结果。我还尝试:
for my $i (@an1) { print @{$b[$i]}; &newl; }
哪些错误是由于0作为数组引用而导致的
Can't use string ("0") as an ARRAY ref while "strict refs" in use at p_disk_ex6.pl line 42.
非常感谢您的任何建议 一个简短的示例程序,可能会帮助您:
use strict;
use warnings;
my @a1 = qw(1MB 2MB 10MB 7MB);
my @a2 = qw(/foo /bar /flub /blub);
my @b = (\@a1, \@a2);
# equivalent long version:
# my @b = ();
# $b[0] = \@a1;
# $b[1] = \@a2;
for (my $i = 0; $i <= $#a2; $i++) {
print "a1[$i]: $b[0][$i]\n";
print "a2[$i]: $b[1][$i]\n";
print "\n";
}
在您编写[@a1,@a2]的示例中,您正在创建一个数组_ref,其中包含连接的数组@a1和@a2(首先是@a1的所有元素,然后是@a2的所有元素):
一个简短的示例程序,可能会帮助您:
use strict;
use warnings;
my @a1 = qw(1MB 2MB 10MB 7MB);
my @a2 = qw(/foo /bar /flub /blub);
my @b = (\@a1, \@a2);
# equivalent long version:
# my @b = ();
# $b[0] = \@a1;
# $b[1] = \@a2;
for (my $i = 0; $i <= $#a2; $i++) {
print "a1[$i]: $b[0][$i]\n";
print "a2[$i]: $b[1][$i]\n";
print "\n";
}
在您编写[@a1,@a2]的示例中,您正在创建一个数组_ref,其中包含连接的数组@a1和@a2(首先是@a1的所有元素,然后是@a2的所有元素):
即使简单地说,这也是可行的
use strict;
use warnings;
my @a1 = qw(1MB 2MB 10MB 7MB);
my @a2 = qw(/foo /bar /flub /blub);
my @b = (@a1, @a2);
print "@b";
即使简单地说,这也是可行的
use strict;
use warnings;
my @a1 = qw(1MB 2MB 10MB 7MB);
my @a2 = qw(/foo /bar /flub /blub);
my @b = (@a1, @a2);
print "@b";
如果您想要一个通用的解决方案,它不假设每个子数组中有多少个元素,并且还允许任意级别的嵌套,那么最好使用其他人已经编写的用于显示递归数据结构的包。一个特别流行的是YAML,如果您还没有通过运行cpan安装它,您可以安装它:
$ cpan
Terminal does not support AddHistory.
cpan shell -- CPAN exploration and modules installation (v1.9800)
Enter 'h' for help.
cpan[1]> install YAML
然后,您可以轻松地显示任意数据结构。用一个简单的例子来演示:
use YAML;
my @a1 = qw(1MB 2MB 10MB 7MB);
my @a2 = qw(/foo /bar /flub /blub);
my @b = (\@a1, \@a2);
print Dump(\@b);
输出结果
---
-
- 1MB
- 2MB
- 10MB
- 7MB
-
- /foo
- /bar
- /flub
- /blub
[ [ 1MB, 2MB, 10MB, 7MB ], [ /foo, /bar, /flub, /blub ], { a => 0, b => 1 } ]
举个稍微复杂一点的例子
my @b = (\@a1, \@a2,
{ a => 0, b => 1 } );
给予
要理解这一点,第1列中的三个“-”字符表示一个包含三个元素的数组。
前两个元素各有四个子元素(第3列中带“-”的行)。这个
第三个外部元素是散列引用,因为它由“key:value”对组成
YAML的一个很好的特性是,您可以使用它将任何递归数据结构转储到文件中,带有子例程引用的除外,然后稍后使用Load将其读回
如果您真的必须运行自己的显示例程,这当然是可能的,但是如果您递归地编写它,您将有一个更轻松的时间。您可以使用ref检查参数是数组引用还是哈希引用(或标量引用):
my @a1 = qw(1MB 2MB 10MB 7MB);
my @a2 = qw(/foo /bar /flub /blub);
my @b = (\@a1, \@a2,
{ a => 0, b => 1 } );
print_recursive(\@b);
print "\n";
sub print_recursive {
my ($obj) = @_;
if (ref($obj) eq 'ARRAY') {
print "[ ";
for (my $i=0; $i < @$obj; $i++) {
print_recursive($obj->[$i]);
print ", " if $i < $#$obj;
}
print " ]";
}
elsif (ref($obj) eq 'HASH') {
print "{ ";
my @keys = sort keys %$obj;
for (my $i=0; $i < @keys; $i++) {
print "$keys[$i] => ";
print_recursive($obj->{$keys[$i]});
print ", " if $i < $#keys;
}
print " }";
}
else {
print $obj;
}
}
我没有编写示例代码来担心漂亮的打印,它也没有
处理标量、子例程或对象引用,但它应该让您了解如何编写一个相当通用的递归数据结构转储程序。如果您想要一个通用解决方案,该解决方案不假定每个子数组中有多少个元素,也允许任意级别的嵌套,最好使用其他人已经编写的用于显示递归数据结构的包。一个特别流行的是YAML,如果您还没有通过运行cpan安装它,您可以安装它:
$ cpan
Terminal does not support AddHistory.
cpan shell -- CPAN exploration and modules installation (v1.9800)
Enter 'h' for help.
cpan[1]> install YAML
然后,您可以轻松地显示任意数据结构。用一个简单的例子来演示:
use YAML;
my @a1 = qw(1MB 2MB 10MB 7MB);
my @a2 = qw(/foo /bar /flub /blub);
my @b = (\@a1, \@a2);
print Dump(\@b);
输出结果
---
-
- 1MB
- 2MB
- 10MB
- 7MB
-
- /foo
- /bar
- /flub
- /blub
[ [ 1MB, 2MB, 10MB, 7MB ], [ /foo, /bar, /flub, /blub ], { a => 0, b => 1 } ]
举个稍微复杂一点的例子
my @b = (\@a1, \@a2,
{ a => 0, b => 1 } );
给予
要理解这一点,第1列中的三个“-”字符表示一个包含三个元素的数组。
前两个元素各有四个子元素(第3列中带“-”的行)。这个
第三个外部元素是散列引用,因为它由“key:value”对组成
YAML的一个很好的特性是,您可以使用它将任何递归数据结构转储到文件中,带有子例程引用的除外,然后稍后使用Load将其读回
如果您真的必须运行自己的显示例程,这当然是可能的,但是如果您递归地编写它,您将有一个更轻松的时间。您可以使用ref检查参数是数组引用还是哈希引用(或标量引用):
my @a1 = qw(1MB 2MB 10MB 7MB);
my @a2 = qw(/foo /bar /flub /blub);
my @b = (\@a1, \@a2,
{ a => 0, b => 1 } );
print_recursive(\@b);
print "\n";
sub print_recursive {
my ($obj) = @_;
if (ref($obj) eq 'ARRAY') {
print "[ ";
for (my $i=0; $i < @$obj; $i++) {
print_recursive($obj->[$i]);
print ", " if $i < $#$obj;
}
print " ]";
}
elsif (ref($obj) eq 'HASH') {
print "{ ";
my @keys = sort keys %$obj;
for (my $i=0; $i < @keys; $i++) {
print "$keys[$i] => ";
print_recursive($obj->{$keys[$i]});
print ", " if $i < $#keys;
}
print " }";
}
else {
print $obj;
}
}
我没有编写示例代码来担心漂亮的打印,它也没有
处理标量、子例程或受祝福的对象引用,但它应该让您了解如何编写一个相当通用的递归数据结构转储程序。我还尝试了以下for循环:
对于我的$I(@b){print{$I};&newl;}
,没有任何运气。在使用“严格引用”时,我收到了相同的错误“无法使用字符串“0”作为数组引用”。我不确定为什么会看到此错误,为什么0会被解释为字符串?我还尝试了以下for循环:对于我的$I(@b){print@{$I};&newl;}
,运气不佳。我收到了相同的错误“无法使用字符串“0”在使用“严格引用”时作为数组引用。我不确定为什么会看到此错误,为什么将0解释为字符串?