Arrays Perl:正确打印数组数组(取消引用)

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

各位僧侣

我仍在思考如何正确地取消引用。(我在发帖之前读过类似的帖子,但不幸的是我对这个概念还是有点模糊。)

我有以下数组,它在内部由两个数组组成。(顺便说一句,我使用的是严格和警告的pragmas。)

其中:

@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解释为字符串?