Perl 使用foreach&;拼接以替换阵列中的2个或多个图元

Perl 使用foreach&;拼接以替换阵列中的2个或多个图元,perl,foreach,indexing,Perl,Foreach,Indexing,我试图通过使用foreach循环将2个关键字替换为新字符串来修改现有数组,但我了解到,在拼接数组时,perl在索引方面存在一些问题。实现此逻辑的另一种/更好的方法是什么?您通过$count对索引进行迭代(这不是计数而是索引),但在查看是否是停止循环的时候,您并没有实际使用它 通常,当您想要迭代索引时,您会使用 @array = {....,.....,...., "keyword1", ....., ..... "keyword2, ....., ....); foreach my $item

我试图通过使用foreach循环将2个关键字替换为新字符串来修改现有数组,但我了解到,在拼接数组时,perl在索引方面存在一些问题。实现此逻辑的另一种/更好的方法是什么?

您通过
$count
对索引进行迭代(这不是计数而是索引),但在查看是否是停止循环的时候,您并没有实际使用它

通常,当您想要迭代索引时,您会使用

@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++;
}
但这在这里是行不通的,因为你把数组元素的索引搞得一团糟。您可以使用
while
循环,如下代码所示:(C风格的for循环只是一个奇特的
while
循环。)

map
用于将一个列表转换为另一个列表,因此也可以在此处使用。使用
map
,您不必担心索引变量的更改量不正确

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";
   }
}

这里有几个问题:

在数组上使用
for
循环时,每个项目都是数组中项目的别名:

@a = map {
   if    (/keyword1/) { qw( word1 word2 word3 ), $_  }
   elsif (/keyword2/) { 'word4', $_                  }
   else               { $_                           }
} @a;
这将打印出“
0:1:2:3:suppirse@!:5

因此,当您更改
for
循环中的项目时,即使您没有使用
$\ucode>,您仍然可以直接访问该循环

在每个时间段中添加数组中间的项可能会导致问题。此外,您正在使用变量

$count
,但从未定义其初始值。始终包括:

#! /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;
在你的脚本中

要执行您想要的操作,我建议您使用两个单独的数组,并从第一个数组复制到第二个数组。这将解决你的很多问题

use strict;
use warnings;

不要修改使用foreach循环进行迭代的数组。这段代码甚至比不上可编译的Perl。你到底在干什么?真正的代码是什么样子的?语法突出显示应该提示您在开始时有一些未终止的构造。也就是说,用
{
而不是
.err,拼接不会复制任何标量,更不用说所有标量了。为什么要放弃
map
解决方案?在我看来,这是最容易避免混乱的方法,也是最容易读取的方法。当然,这有两个很好的理由。@Miller,为了避免我写新的介绍文本。重新引入。我甚至格式化了块的c内容更好。@Miller,看来你是在做梦,通过比较
perl-MO=constructe,-exec-we'for(reverse 1..10){}
perl-MO=constructe,-exec-we'for(1..10){/code>的输出,从1..10生成一个数组,然后反向循环。@Miller,在
for(reverse LIST)中
反向
被优化掉,并替换为一个告诉foreach向后的标志。但是列表仍然是平坦的,即使它是一个范围。(它在编译时是平坦的,它是一个常量范围!)
#! /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;
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;