使用foreach& splice以替换数组中的2个或更多元素

时间:2014-03-19 19:02:03

标签: perl foreach indexing

@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在数组被拼接时有一些索引问题。什么是实现此逻辑的替代/更好的方法?

2 个答案:

答案 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;