in reply to add elements to array at certain positions

my $i = 0; my @new = map { /^[yz]$/ ? 'I' : $a[$i++] } @b;

Replies are listed 'Best First'.
Re^2: add elements to array at certain positions
by coldy (Scribe) on Oct 30, 2008 at 05:19 UTC
    Thanks. Is there a similar method if the arrays are strings?

      split the string(s) into a list of characters, use the map as shown, then join the result back together.


      Perl reduces RSI - it saves typing

      The method demonstrated below is devious and should be avoided in favour of something more conventional.

      my $stra = '0157953'; my $strb = 'abcyefzaa'; (my $new = $strb) =~ s/([yz])|./ (defined($1) ? 'I' : ($stra =~ m{(.)}sgc ? $1 : die ) ) /seg; print("$new\n"); # 015I79I53

      Update: Saner: (no nesting)

      my $stra = '0157953'; my $strb = 'abcyefzaa'; my $new = ''; while ($strb =~ /([yz])|./sg) { $new .= (defined($1) ? 'I' : ($stra =~ /(.)/sgc ? $1 : die ) ); } print("$new\n"); # 015I79I53
Re^2: add elements to array at certain positions
by juster (Friar) on Oct 30, 2008 at 06:49 UTC

    $i should increment each time or else the value in @a that we didn't want will still be printed after the 'I'

    my $i = 0; my @new = map { ++$i; /^[yz]$/ ? 'I' : $a[$i] } @b;

    A solution I thought of with List::MoreUtils:

    use List::MoreUtils qw(pairwise); my @mine = pairwise { $b =~ /^[yz]$/ ? 'I' : $a; } @a, @b;

    Mine is not as nice because it doesn't work properly if both arrays are not the same size. You would have to add a check for undefined values or pad either array to match the other array's size. Perl also warns that $a and $b are only used once.

      The OP's example made it clear that no values from @a were to be skipped. $i should not increment each time, and even if it should, it should either be set to -1 before the 'loop', or incremented after the ternary. Your sample preincrements $i so $a[0] would always be skipped.


      Perl reduces RSI - it saves typing

        Oops, I'm sorry! I will stop posting at night before sleep. Here is a fast List::MoreUtils alternative that actually does what the OP asks for this time:

        use List::MoreUtils qw(indexes); my $a = '0157953'; my $b = 'abcyefzaa'; my $new = $a; substr $new, $_, 0, 'I' foreach ( indexes { $_ =~ /^[yz]$/ } split(//, $b) ); print $new, "\n";

        Update: I just realized this nearly identical loop is much faster (nested update: oops it's pos-1):

        substr $new, pos($b)-1, 0, 'I' while ( $b =~ /[yz]/g );