@array = {....,.....,...., "keyword1", ....., ..... "keyword2, ....., ....);
foreach my $item(@array)
{
if ($item =~ /keyword1/)
{
splice @array, $count, 0, "word1", "word2", "word3";
}
elsif ($item =~ /keyword2/)
{
splice @array, $count, 0, "word4";
}
$count++;
}
我试图通过使用foreach循环用新字符串替换2个关键字来修改现有数组,但我读到perl在数组被拼接时有一些索引问题。什么是实现此逻辑的替代/更好的方法?
答案 0 :(得分:2)
你通过$count
迭代索引(这不是一个计数而是一个索引),但实际上并没有使用它来查看是否有时间停止循环!
通常,当你想迭代索引时,你会使用
for my $i (0..$#a) {
... $a[$i] ...
}
但是由于你搞乱了数组元素的索引,所以这不会起作用。您可以进行while
循环,如下面的代码所示:( C循环的C风格只是一个花哨的while
循环。)
for (my $i=0; $i<@a; ++$i) {
if ($a[$i] =~ /keyword1/) {
splice @a, $i, 0, qw( word1 word2 word3 );
$i += 3;
}
elsif ($a[$i] =~ /keyword2/) {
splice @a, $i, 0, "word4";
$i += 1;
}
}
在这种情况下,反向迭代更容易。
for (my $i=@a; $i--; ) {
if ($a[$i] =~ /keyword1/) {
splice @a, $i, 0, qw( word1 word2 word3 );
}
elsif ($a[$i] =~ /keyword2/) {
splice @a, $i, 0, "word4";
}
}
map
用于将一个列表翻译成另一个列表,因此也可以在此处使用。使用map
,您不必担心将索引变量更改为错误的数量。
@a = map {
if (/keyword1/) { qw( word1 word2 word3 ), $_ }
elsif (/keyword2/) { 'word4', $_ }
else { $_ }
} @a;
答案 1 :(得分:0)
这里有一些问题:
在数组上使用for
循环时,每个项目都是数组中项目的别名:
#! /usr/bin/env perl
#
use warnings;
use strict;
use feature qw(say);
my @array = qw(zero one two three four five);
for my $value ( @array ) {
if ( $value eq "four" ) {
$value = "SURPIRSE!";
}
}
say join ": ", @array;
打印出“zero: one: two: three: SURPIRSE@!: five
”
因此,当您更改for
循环中的项目时,即使您没有使用$_
,您仍然可以直接访问该循环。
每次执行时在数组中间添加项可能会导致问题。此外,您正在使用变量$count
,但从未定义其初始值。始终包括:
use strict;
use warnings;
在你的脚本中!
为了做你想做的事情,我建议你使用两个独立的数组并从第一个数组复制到第二个数组。这将解决您的许多问题。
#! /usr/bin/env perl
#
use warnings;
use strict;
use feature qw(say);
my @array = qw(zero one two keyword1 three four keyword2 five);
my @new_array;
for my $value ( @array ) {
if ( $value eq "keyword1" ) {
push @new_array, "word1", "word2", "word3";
}
elsif ( $value eq "keyword2" ) {
push @new_array, "word3";
}
else {
push @new_array, $value;
}
}
say join ": ", @new_array;