As ysth has already pointed out, it is unwise to attempt to modify an array while iterating directly on its elements.
However, if one does want to modify an array dependent on the element values, the trick is to do it in reverse index order.
For example, say I have an array of numbers. I would like modifier the array so that every multiple of 4 has a string inserted after it, and every multiple of 5 is removed. I would accomplish that using the following:
use strict;
use warnings;
my @array = ( 1 .. 20 );
for my $i ( reverse 0 .. $#array ) {
# Insert after multiples of 4
if ( ( $array[$i] % 4 ) == 0 ) {
splice @array, $i + 1, 0, "insert";
}
# Remove multiples of 5
if ( ( $array[$i] % 5 ) == 0 ) {
splice @array, $i, 1;
}
}
use Data::Dump;
dd @array;
Outputs:
(
1 .. 4,
"insert",
6,
7,
8,
"insert",
9,
11,
12,
"insert",
13,
14,
16,
"insert",
17,
18,
19,
"insert",
)
Alternatively, if you want to transform an array, it's also possible to use map
like so:
my @newarray = map {
( ( ($_) x !!( $_ % 5 ) ), # Remove multiples of 5
( ('insert') x !( $_ % 4 ) ), # Insert After multiples of 4
)
} ( 1 .. 20 );
use Data::Dump;
dd @newarray;