Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

splicing two arrays together

by lblake (Novice)
on Jan 05, 2012 at 23:16 UTC ( #946492=perlquestion: print w/ replies, xml ) Need Help??
lblake has asked for the wisdom of the Perl Monks concerning the following question:

Hello wise ones,

I've managed to splice two arrays of strings together to make one sentence. However, there's something wrong with the final outcome which is: Can you unlock the the secret code? I am not clear on why there are two 'the the'?

Here's the code I used:
#!/usr/bin/perl use strict; use warnings; my @first = qw(Can unlock secret); my @second = qw(you the code?); print "Array contents of first array before splice: @first\n"; print "Array contents of second array before splice: @second\n"; splice(@first, 1, 0, @second[0,-2]); print "After splice the array contains: @first\n"; my @newArray = @first; splice(@newArray, 5,0,@second[0,2]); print "After splice the array contains: @newArray\n"; my @newArray1 = @newArray; splice(@newArray1, 2,1); print "After splice the Array1 contains: @newArray1\n"; my @newArray2 = @newArray1; splice(@newArray2, 4,1); print"After splice the Array2 contains: @newArray2\n"; my @newArray3 = @newArray2; splice(@newArray3,3,0, @second[1,1]); print "Final splice Array3 contains: @newArray3\n";
I am not even sure if this is the best way to use the splice function to achieve my goal? Thanks

Comment on splicing two arrays together
Download Code
Re: splicing two arrays together
by ~~David~~ (Hermit) on Jan 05, 2012 at 23:50 UTC
    Here is one way:
    use strict; use warnings; my @first = qw(Can unlock secret); my @second = qw(you the code?); my $i = 1; while ( my $word = shift @second ){ splice @first, $i, 0, $word; $i += 2; } print join ' ', @first;
      Or like this maybe:
      use strict; use warnings; my @first = qw(Can unlock secret); my @second = qw(you the code?); my $result = join " ", map { ($first[$_], $second[$_]) } (0..$#first); print $result;
Re: splicing two arrays together
by GrandFather (Cardinal) on Jan 06, 2012 at 00:24 UTC

    I wouldn't use splice at all. Instead I'd merge the two arrays:

    #!/usr/bin/perl use strict; use warnings; my @first = qw(Can unlock secret); my @second = qw(you the code?); my @interleave; push @interleave, grep {$_} (shift @first), shift @second while @first || @second; print "@interleave";

    Although you could use splice to do an "in place' merge:

    #!/usr/bin/perl use strict; use warnings; my @first = qw(Can unlock secret); my @second = qw(you the code?); splice @first, @second, 0, pop @second while @second; print "@first";

    or avoiding destroying the contents of @second:

    ... splice @first, $_, 0, $second[$_ - 1] for reverse 1 .. @second; print "@first";

    or using splice to populate a new array:

    my @new; splice @new, 0, 0, $first[$_], $second[$_] for reverse 0 .. $#second; print "@new";

    Note that a few of these do stuff backwards to avoid having to account for elements that have been inserted into the target array.

    Now, to answer your actual question. First lets add diagnostics a little differently to your existing code:

    #!/usr/bin/perl use strict; use warnings; my @first = qw(Can unlock secret); my @second = qw(you the code?); dumpArrays('start', \@first, \@second); splice(@first, 1, 0, @second[0,-2]); dumpArrays('first', \@first, \@second); my @newArray = @first; splice(@newArray, 5,0,@second[0,2]); dumpArrays('na', \@first, \@second, \@newArray); my @newArray1 = @newArray; splice(@newArray1, 2,1); dumpArrays('na1', \@first, \@second, \@newArray1); my @newArray2 = @newArray1; splice(@newArray2, 4,1); dumpArrays('na2', \@first, \@second, \@newArray2); my @newArray3 = @newArray2; splice(@newArray3,3,0, @second[1,1]); dumpArrays('na3', \@first, \@second, \@newArray3); sub dumpArrays { my ($msg, @arrays) = @_; printf "%-10s %s\n", $msg, join '|', map {"@$_"} @arrays; }

    Prints:

    start Can unlock secret|you the code? first Can you the unlock secret|you the code? na Can you the unlock secret|you the code?|Can you the unlock +secret you code? na1 Can you the unlock secret|you the code?|Can you unlock secr +et you code? na2 Can you the unlock secret|you the code?|Can you unlock secr +et code? na3 Can you the unlock secret|you the code?|Can you unlock the +the secret code?

    Note that the error doesn't happen until the very last step. In that step you splice(@newArray3,3,0, @second[1,1]);. @second[1,1] which inserts two copies of the word 'the'. You just needed $second[1] there.

    True laziness is hard work
Re: splicing two arrays together
by i5513 (Monk) on Jan 06, 2012 at 00:36 UTC

    "I am not clear on why there are two 'the the'?"

    That is because you are doing:

    splice(@newArray3,3,0, @second[1,1]);

    So you are inserting 2 elements "the" in @newArray3 at third position

    See  print "@second[1,1]" output .. and slices to understand it
    Regards,
Re: splicing two arrays together
by ikegami (Pope) on Jan 06, 2012 at 01:46 UTC
    use List::MoreUtils qw( mesh ); my @first = qw( Can unlock secret ); my @second = qw( you the code? ); my @newArray = mesh @first, @second;

    List::MoreUtils

    Update: Fixed code to adjust to mesh's unusual prototype.

Re: splicing two arrays together
by TJPride (Pilgrim) on Jan 06, 2012 at 05:08 UTC
    use strict; use warnings; my @first = qw(Can unlock secret); my @second = qw(you the code?); splice(@first, $_+1, 0, $second[$_]) for reverse 0..$#second; print "@first\n";

    I notice this is fairly close to one of GrandFather's solutions, but that's really because there is only one best way to do this if the requirement is to use splice.

      This is a trivial variant of one of the three different splice based options I provided. So which of the trivial variations is "the one best way" to do it? How is this "the best way" if preserving the content of @first is desired? What non-artificial context would require the use of split?

      Remember an oft quoted virtue of Perl is TIMTOWTDI with the strong implication that there is seldom a "single best solution". Actually even with languages that tout themselves as offering the "one true way" there is seldom a single "best" solution to any problem.

      True laziness is hard work
        Thanks Grandfather for those solutions, the best solution I guest is the one that requires the least amount of typing in any language?
        Actually, it's an independent solution that just happens to be mostly identical to yours. My determination of "best" is that the OP asked for a solution with splice, and this was the best solution possible with splice. Obviously, splice is not the most efficient way to do this overall, but that's the OP's problem, since he framed the question in the context of splice rather than the context of finding the most efficient way to do merge two arrays. I'm guessing it's a homework problem and they said he had to use splice.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://946492]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (9)
As of 2014-11-27 18:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (187 votes), past polls