2009-10-15 3 views
2

Я создал массив следующим образомКак я могу перебирать вложенные массивы?

while (defined ($line = `<STDIN>`)) 

     { 
     chomp ($line); 
     push @stack,($line); 
     } 

каждая строка имеет два номера.

15 6 
2 8 

Как выполнить перебор по каждому элементу в каждой строке?

то я хочу, чтобы напечатать

15 
6 
2 
8 

Я понимаю, что это что-то вроде

foreach (@{stack}) (@stack){ 

    print "????? 
} 

Это где я застрял.

+4

Не понимаю, как то, что вы хотите распечатать, отличается от того, что у вас есть. Кроме того, эти backticks не выглядят правильно. – 2009-10-15 10:33:04

+1

То же самое на задних скоростях. Удалите их и используйте 'while (my $ line = <>)'. –

+0

'while (my $ line = <>)' автоматически преобразуется в 'while (определяется (my $ line = <>))' –

ответ

10

См. Документацию perldsc. Это Perbook Data Structures Cookbook, в которой есть примеры для работы с массивами массивов. Из того, что вы делаете, похоже, вам не нужен массив массивов.

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

while(<>) { 
    s/\s+/\n/; # turn all whitespace runs into newlines 
    print;  # it's ready to print 
    } 

С Perl 5.10, вы можете использовать новый класс \h символов, который соответствует только по горизонтали пробельные:

while(<>) { 
    s/\h+/\n/; # turn all horizontal whitespace runs into newlines 
    print;  # it's ready to print 
    } 

в Perl однострочника, это просто:

% perl -pe 's/\h+/\n/' file.txt 
0
#!/usr/bin/perl 

while ($line = <STDIN>) { 
    chomp ($line); 
    push @stack, $line; 
} 

# prints each line 
foreach $line (@stack) { 
    print "$line\n"; 
} 

# splits each line into items using ' ' as separator 
# and prints the items 
foreach $line (@stack) { 
    @items = split//, $line; 

    foreach $item (@items) { 
     print $item . "\n"; 
    } 
} 
+0

Должен ли последний «for» быть «foreach»? – dave

+0

Foreach было бы более легко понять, от perldoc perlsyn: > Ключевое слово «foreach» на самом деле является синонимом ключевого слова «для», поэтому вы можете использовать «foreach» для удобочитаемости или «для» для краткости. – 2009-10-15 11:18:40

+1

'foreach' и' for' ведут себя одинаково. Многие перлы предпочитают использовать 'for' исключительно. – hobbs

0

Я использую «для» для петель стиля «С» и «foreach» для итерации по спискам.

+0

Нет необходимости проводить такое искусственное различие между ними. –

+0

Нет необходимости, но это то, что я тоже делаю. Это просто синтаксический сахар. – Ether

+0

Я использую 'for' для обоих. Циклы стиля C будут записаны с помощью 'loop' в Perl6, а' foreach' будет переименован в 'for' –

8
#!/usr/bin/perl 

use strict; 
use warnings; 

while (my $data = <DATA>) { 
    my @values = split ' ', $data; 
    print $_, "\n" for @values; 
} 


__DATA__ 
15 6 
2 8 

Выход:

 
C:\Temp> h 
15 
6 
2 
8 

В качестве альтернативы, если вы хотите сохранить каждую строку в @stack и распечатать позже:

my @stack = map { [ split ] } grep { chomp; length } <DATA>; 

Линия выше хлебает все исходящее от DATA файлового дескриптора в список (потому что <DATA> происходит в контексте списка). grep chomps каждую строку и фильтрует по длине после chomping (чтобы избежать получения каких-либо завершающих пустых строк в файле данных - вы можете избежать этого, если их нет). Затем map разбивает каждую строку вдоль пробелов, а затем создает ссылку на анонимный массив для каждой строки. Наконец, такие ссылки на массивы хранятся в каждом элементе @stack. Вы можете использовать Data::Dumper, чтобы посмотреть на @stack, чтобы понять, что происходит.

print join("\n", @$_), "\n" for @stack; 

Теперь мы смотрим на каждую запись в стеке, разыменования каждый массив в свою очередь, затем соединения элементов каждого массива с новой строкой, чтобы напечатать один элемент в каждой строке.

Выход:

 
C:\Temp> h 
15 
6 
2 
8 

Долгий путь написания по существу то же самое (с меньшим потреблением памяти) будет:

my @stack; 

while (my $line = <DATA>) { 
    last unless $line =~ /\S/; 
    my @values = split ' ', $line; 
    push @stack, \@values; 
} 

for my $ref (@stack) { 
    print join("\n", @$ref), "\n"; 
} 

Наконец, если вы хотите сделать что-то другое, чем печать всех значений , скажем, суммировать все числа, вы должны сохранить одно значение на элемент @stack:

use List::Util qw(sum); 

my @stack; 

while (my $line = <DATA>) { 
    last unless $line =~ /\S/; 
    my @values = split ' ', $line; 
    push @stack, @values; 
} 

printf "The sum is %d\n", sum @stack; 
0
#!/usr/bin/perl 

use strict; 
use warnings; 
open IN, "< read.txt" or 
    die "Can't read in 'read.txt'!"; 

my $content = join '', <IN>; 

while ($content =~ m`(\d+)`g) { 
    print "$1\n"; 
} 
Смежные вопросы