如果$a
是一个数组数组,则下面的代码有效,但我需要$a
作为数组数组的引用。
问题
如何遍历$a
?
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
my @AoA = ( ['aaa','hdr','500'],
['bbb','jid','424'],
['ccc','rde','402'],
);
my $a = \@AoA;
my $s = "bbb";
my $d = "ddd";
for my $i ( 0 .. $#a ) {
for my $j ( 0 .. $#{ $a[$i] } ) {
if ($a[$i][$j] eq $s) {
$a[$i][$j] = $d;
last;
}
}
}
print Dumper $a;
答案 0 :(得分:14)
foreach my $row (@$array_ref) {
foreach my $cell (@$row) {
if ($cell eq $s) {
$cell = $d;
last;
}
}
}
另外,要计算数组引用中的元素数(从上面的代码中可以看出,您不需要特定的代码),最简单的方法是:
my $count = scalar(@$array_ref);
my $row_count = scalar(@{ $array_ref->[$i] });
my $last_index = $#$array_ref;
另外,要访问arrayrefs的arrayref内的数据,只需在其上使用dereference运算符:
$array_ref->[$i]->[$j]; # The second arrow is optional but I hate omitting it.
此外,你可以像你所做的那样创建arrayrefs的arrayref(引用数组数组),或者立即创建它作为参考:
my $array_ref = [
[1,2,3]
,[4,5,6]
];
作为旁注,请不要使用$a
和$b
作为标识符名称 - 它们有特殊用途(例如用于排序块)
答案 1 :(得分:3)
要在Perl中取消引用,您有多种选择。对于初学者,我建议你阅读perlref。以下是相关代码部分,只需更改,因此您可以看到需要进行哪些更改(但是,我同意其他人的建议,以使您的代码更加Perlish)。
for my $i ( 0 .. $#$a ) {
for my $j ( 0 .. $#{ $a->[$i] } ) {
if ($a->[$i][$j] eq $s) {
$a->[$i][$j] = $d;
last;
}
}
}
答案 2 :(得分:3)
在我看来,最简单的取消引用方法是始终记住数组和散列只能包含标量值(请参阅perldoc perldata)。这意味着你的数组
my @AoA = ( ['aaa','hdr','500'],
['bbb','jid','424'],
['ccc','rde','402']);
...只包含三个标量值,它们是对其他数组的引用。你可以这样写:
my $first = [ qw(aaa hdr 500) ]; # using qw() which will quote the args
my $sec = [ qw(bbb jid 424) ];
my $third = [ qw(ccc rde 402) ];
my @all = ($first, $sec, $third); # this array is now identical to @AoA
考虑到这一点,很容易想象(就像DVK在他的回答中建议的那样)一个循环,例如:
for my $aref (@all) {
# $aref will contain $first, $sec, and $third
}
知道$aref
是一个数组引用,解除引用很简单:
for my $aref (@all) {
for my $value (@$aref) {
# do your processing here
}
}
此外,由于for循环中的值是别名,因此对它们的任何更改都会影响原始数组。因此,如果上面循环中的“处理”包含诸如
之类的赋值$value = $foo;
这意味着@all
中的值也会发生变化,就像你写的那样:
$all[0][1] = $foo;
答案 3 :(得分:1)
我发现使用“last”是模糊的,内在的或外在的,所以我明确表示。
for (@$a) {
INNER:
for (@$_) {
do {$_ = $d; last INNER} if $_ eq $s;
}
}
答案 4 :(得分:1)
每当我处理数组或散列或散列数组或数组散列数组时,我就开始考虑面向对象编程。 Perl OOP并不是那么复杂,它隐藏了很多逻辑复杂性。
现在,在这个非常简单的例子中,只是在没有面向对象的情况下编写它会更容易,而且你已经有了几个很好的答案(你主要忘了取消引用你的引用)。
但是一旦你开始意识到你可以在Perl中拥有比简单的哈希,数组和标量更复杂的结构,你的数据结构就会变得越来越复杂,而且没有OOP就越难解析。
#!/usr/bin/env perl
use strict;
use warnings;
use feature qw(say);
my $a_of_a = array_of_arrays->new;
$a_of_a->push(["aaa", "hdr", "500"]);
$a_of_a->push(["bbb", "jid", "424"]);
$a_of_a->push(["ccc", "rde", "402"]);
foreach my $member ($a_of_a->list) {
my @array = @{$member};
foreach my $element (@array) {
printf "%-5.5s ", $element;
}
print "\n";
}
package array_of_arrays;
sub new {
my $class = shift;
my $self = [];
bless $self, $class;
return $self;
}
sub push {
my $self = shift;
my $item = shift;
push @{$self}, $item;
return $self;
}
sub pop {
my $self = shift;
if (scalar @{$self}) {
return pop @{$self};
}
else {
return;
}
}
sub list {
my $self = shift;
return @{$self};
}
答案 5 :(得分:0)
for my $x (@{$a}) {
for (@{$x}) {
if ($_ eq $s) {
$_ = $d;
last;
}
}
}