2010-09-13 3 views
1

Я пытаюсь перебирать 2D-массив, который структурирован таким образом. Независимо от того, является ли это хорошим способом структурирования массива, возникает другой вопрос - мне все же нужно иметь возможность перебирать его (если это возможно).Perl: Итерация через этот фанковый массив?

@row1 = ("Current Scan", "Last Month"); 
@row2 = ("240", "0"); 
@row3 = ("226", "209"); 
@row4 = ("215", "207"); 

@array = (\@row1, \@row2, \@row3, \@row4); 
print Dumper(@array); 
printarray(@array); 

Хранитель дает мне следующий вывод:

$VAR1 = [ 
      'Current Scan', 
      'Last Month' 
     ]; 
$VAR2 = [ 
      '240', 
      '0' 
     ]; 
$VAR3 = [ 
      '226', 
      '209' 
     ]; 
$VAR4 = [ 
      '215', 
      '207' 
     ]; 

Я пытался несколько для шлейфов без успеха. Каждый печатает только первую строку ($ VAR1) и завершает работу. Вот моя последняя попытка:

sub printarray { 
    @array = shift; 
    $rowi = 0; 
    foreach my $row (@array) { 
    for (my $coli = 0; $coli <= @$row; $coli++) { 
     print "$array[$rowi][$coli]\n"; 
    } 
    $rowi++; 
    } 
} 

Я, очевидно, пропускаю что-то простое. Что я делаю не так? Заранее спасибо!

+0

Не уверен, что результат вы ожидаете, но есть ошибка в использовании 'length' функции. Это вам не нужно, поскольку возвращает длину строки. Используйте '$ coli <@ $ row' для условия цикла. –

+0

Спасибо, я отредактировал его, чтобы надеяться сделать его более понятным. Я просто пытаюсь выполнить итерацию по всему массиву, и по какой-то причине он проходит только первую строку. – Magicked

+1

Я забыл очень важную часть, я думаю. Сначала я подумал, что это только то, что я закрутил итерацию, но я забыл, что передал ее через подпрограмму ... Я предполагаю, что это проблема ... – Magicked

ответ

10

Если вы хотите просто напечатать массив, попробуйте следующий код:

foreach my $row (@array) { 
    foreach my $elem (@$row) { 
     print $elem; ## print elements without separator 
    } 
    print "\n"; ## new line after row 
} 

Если вам нужны индексы для какой-то цели, здесь мы идем:

for(my $row_i = 0; $row_i < @array; $row_i++) { 
    for(my $column_i = 0; $column_i < @{ $array[$row_i] }; $column_i++) { 
     print $array[$row_i][$column_i]; 
    } 
} 

Идея заключается в том, что @array в скаляр context возвращает количество элементов в массиве. И @{ $array[$row_i] } немного сложнее. Этот массив разыменования хранится в $array[$row_i].

Обновление для подпрограммы:

В Perl'е вы можете передать массив по ссылке:

printarray(\@array); ## pass reference 

sub printarray { 
    my $array_ref = shift; ## no copy created 

    foreach my $row (@$array_ref) { ## now we need to dereference 
     ... 
    } 
} 

Вы также можете передать копию массива:

printarray(@array); 

sub printarray { 
    my @array_copy = @_; ## store local copy of array 
    ... 
} 

Более подробно принять посмотрите на страницу справочника How can I pass/return a {Function, FileHandle, Array, Hash, Method, Regex}?.

И, пожалуйста, добавьте use strict; в начале программы. Это заставит вас объявить все переменные, но сохранит кучу времени, если вы напечатаете что-то неправильно.

+0

Спасибо. Я оставил еще более важную часть выше. Я был настолько сосредоточен на части итерации, что забыл, что прошел через подпрограмму ... Я думаю, что это проблема. – Magicked

+0

Это сделало трюк. Спасибо! – Magicked

1
 
    #!/usr/bin/perl 
    use warnings; 
    use strict; 

    my @row1 = ("Current Scan", "Last Month"); 
    my @row2 = ("240", "0"); 
    my @row3 = ("226", "209"); 
    my @row4 = ("215", "207"); 

    my @array = (\@row1, \@row2, \@row3, \@row4); 

    foreach my $row (@array) { 
    foreach my $value (@$row) { 
     print "$value\n"; 
    } 
    } 

Это напечатает

 
    Current Scan 
    Last Month 
    240 
    0 
    226 
    209 
    215 
    207 

Не уверен, если это то, что вы хотели.

1

Да, проблема в том, как передать массив в подпрограмму. Perl выравнивает массивы в списках параметров. В основном, printarray(@array) (в этом примере) эквивалентен printarray($array[0], $array[1], $array[2], $array[3]). shift в начале printarray принимает первый параметр и назначает его @array. Так что, независимо от того, насколько велик массив, printarray видит только первый элемент.

3

Когда вы передаете массив в подпрограмму, вы по существу передаете восемь скаляров. Затем, когда вы сделаете

sub printarray { 
    @array = shift; 

...вы выпадаете только первый элемент в списке. Попробуйте:

sub printarray { 
    @array = @_; 
0

Вы ищете что-то вроде этого:

#!/usr/bin/perl 
use warnings; 
use strict; 
use Algorithm::Loops 'MapCar'; 

my @row1 = ("Current Scan", "Last Month"); 
my @row2 = ("240", "0"); 
my @row3 = ("226", "209"); 
my @row4 = ("215", "207"); 

my @array = (\@row1, \@row2, \@row3, \@row4); 

MapCar { print "Scan: $_[0]: $_[1], $_[2], $_[3]\n" } @array; 
Смежные вопросы