Редкий случай, когда подходит цикл в стиле C для итерации по каждому третьему элементу
my $string = 'aaa 111 AAA bbb 222 BBB ccc 333 CCC ddd 444 DDD';
my (@sep1, @sep2, @sep3);
my @values = split ' ', $string;
for (my $i=0; $i <= $#values; $i += 3) {
push @sep1, $values[$i];
push @sep2, $values[$i+1];
push @sep3, $values[$i+2];
}
Это предполагает, что массив действительно имеет все триплеты, или лучше проверить каждый элемент.
Но обычно гораздо удобнее работать с одной структурой, чем с набором параллельных массивов. Например, используйте массив с элементами, которые являются ссылками на массив
use Data::Dump qw(dd);
my @sep;
for (my $i=0; $i <= $#values; $i += 3) {
for my $j (0..2) {
push @{$sep[$j]}, $values[$i+$j];
}
}
dd \@sep;
где двойной итерации можно избежать с помощью гораздо более чистого
for my $i (0..$#values) {
push @{$sep[$i%3]}, $values[$i]
}
, который заменяет две петли.
Это печатает
[
["aaa", "bbb", "ccc", "ddd"],
[111, 222, 333, 444],
["AAA", "BBB", "CCC", "DDD"],
]
Я использую Data :: Dump для просмотра сложных данных. Альтернативой в ядре является Data :: Dumper .
И еще есть много модулей со всеми видами утилит для работы со списками.
Например, используя part из List :: MoreUtils , чтобы разбить массив @values
my @sep = map { [ @values[@$_] ] } part { $_%3 } 0..$#values;
Это выдает тот же @sep
с массивами, как указано выше.
part
возвращает список arrayrefs, каждый из которых содержит индексы, поскольку он разделил список индексов @values
. Затем в map каждый массив ссылается на свой список индексов (@$_
), который используется для взятия соответствующего среза @values
; этот список используется для создания массива с []
. Так что map
возвращает список arrayrefs со значениями, разделенными по мере необходимости.
Для работы со ссылками см. Учебник perlreftut и справку perlref