简体   繁体   English

在Perl中引用2D数组中的元素

[英]Referencing an element in a 2D array in Perl

I have the following code which reads in a 6x6 array from STDIN and saves it as an array of anonymous arrays. 我有以下代码,该代码从STDIN读取6x6数组并将其保存为匿名数组的数组。 I am trying to print out each element with $arr[i][j] , but the code below isn't working. 我正在尝试使用$arr[i][j]打印每个元素,但是下面的代码不起作用。 It just prints out the first element over and over. 它只是一遍又一遍地打印出第一个元素。 How am I not accessing the element correctly? 我如何无法正确访问元素?

#!/user/bin/perl

my $arr_i = 0;
my @arr = ();
while ($arr_i < 6){
    my $arr_temp = <STDIN>;
    my @arr_t = split / /, $arr_temp;
    chomp @arr_t;
    push @arr,\@arr_t;
    $arr_i++;
}
foreach my $i (0..5){
    foreach my $j (0..5){
        print $arr[i][j] . "\n";
    }
}

i and j are not the same as the variables you declared in the foreach lines. ij与您在foreach行中声明的变量不同。 Change: 更改:

print $arr[i][j] . "\n";

to: 至:

print $arr[$i][$j] . "\n";

warnings alerted me to this issue. warnings我意识到了这个问题。 You should add these lines to all your Perl code: 您应该将以下行添加到所有Perl代码中:

use warnings;
use strict;

To demonstrate the Perlish mantra that there's "more than one way to do it": 为了证明Perlish的口头禅,“有多种方法可以做到这一点”:

use 5.10.0; # so can use "say"
use strict;
use warnings qw(all);

sub get_data {
  my ($cols, $rows) = @_;
  my ($line, @rows);
  my $i;
  for ($i = 1; $i <= $rows and $line = <DATA>; $i++) {
    chomp $line;
    my $cells = [ split ' ', $line ];
    die "Row $i had ", scalar(@$cells), " instead of $cols" if @$cells != $cols;
    push @rows, $cells;
  }
  die "Not enough rows, got ", $i - 1, "\n" if $i != $rows + 1;
  \@rows;
}

sub print_data {
  my ($cols, $rows, $data) = @_;
  for (my $i = 0; $i < $rows; $i++) {
    for (my $j = 0; $j < $cols; $j++) {
      say $data->[$i][$j];
    }
  }
}

my $data = get_data(6, 6);
print_data(6, 6, $data);

__DATA__
1 2 3 4 5 6
a b c d e f
6 5 4 3 2 1
f e d c b a
A B C D E F
7 8 9 10 11 12

Explanation: 说明:

  • if we use say , that avoids unsightly print ..., "\\n" 如果我们使用say ,可以避免难看的print ..., "\\n"
  • get_data is a function that can be called and/or reused, instead of just being part of the main script get_data是一个可以调用和/或重用的函数,而不仅是主脚本的一部分
  • get_data knows what data-shape it expects and throws an error if it doesn't get it get_data知道期望的数据形状,如果没有得到它就会抛出错误
  • [ ... ] creates an anonymous array and returns a reference to it [ ... ]创建一个匿名数组并返回对其的引用
  • get_data returns an array-reference so data isn't copied get_data返回数组引用,因此不会复制数据
  • print_data is a function too print_data也是一个功能
  • both functions use a conventional for loop instead of making lists of numbers, which in Perl 5 needs to allocate memory 这两个函数都使用常规的for循环而不是创建数字列表,这在Perl 5中需要分配内存

There is also a two-line version of the program (with surrounding bits, and test data): 该程序还有两行版本(带有周围的位和测试数据):

use 5.10.0; # so can use "say"
my @lines = map { [ split ' ', <DATA> ] } (1..6);
map { say join ' ', map qq{"$_"}, @$_ } @lines;

__DATA__
1 2 3 4 5 6
a b c d e f
6 5 4 3 2 1
f e d c b a
A B C D E F
7 8 9 10 11 12

Explanation: 说明:

  • using map is the premier way to iterate over lists of things where you don't need to know how many you've seen (otherwise, a for loop is needed) 使用map是遍历不需要知道已经看到多少事物的列表的主要方法(否则,需要for循环)
  • the adding of " around the cell contents is only to prove they've been processed. Otherwise the second line could just be: map { say join ' ', @$_ } @lines; 在单元格内容周围添加"仅是为了证明它们已被处理。否则,第二行可能只是: map { say join ' ', @$_ } @lines;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM