Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Using Splice with Two Arrays within a loop

by Anonymous Monk
on Jun 10, 2013 at 15:32 UTC ( #1038101=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I am new to Perl (with no programming experience) so please bare with me. Problem: I am having issues making this work: Using a built-in function splice I need to remove a specified number of elements from the @_ array at once rather than the one-at-a-time that shift does

the original code was:

#!/usr/bin/perl use strict; use warnings; my @first = qw(Can unlock secret); my @second = qw(you the code?); my @mixed = interleave_words( scalar(@first), @first, @second ); print "Result: @mixed\n"; sub interleave_words { my @results; my $count = shift; foreach my $index ( 0 .. $count-1 ) { $results[$index * 2] = shift; } if ( @_ != $count ) { die "Second array not same size ($count) as the first\n"; } foreach my $index ( 0 .. $count-1 ) { $results[$index * 2 + 1] = shift; } return @results; }

I have changed the following code to meet the requirement below:

#!/usr/bin/perl use strict; use warnings; my @first = qw(Can unlock secret); my @second = qw(you the code?); my @mixed = interleave_words( scalar(@first), @first, @second ); print "Result: @mixed\n"; sub interleave_words { my @results; my $count = shift; foreach my $index ( 0 .. $count-1 ) { my @merge_list = splice (@_, 0, 2); # my @merge_list1 = splice (@merge_list, 0, 2+1); print "Result: @merge_list\n"; } if (@_!=$count) { die "Second array not same size ($count) as the first\n"; } return @results; }

but it is not working I am getting wrong output: I should be getting: Result: Can you unlock the secret code?

however I am getting: Result: Can Unlock Result: secret You Result: the Code? Second array not same size (3) as the first

Can someone help me out trying to figure out what I am doing wrong or missing out

Comment on Using Splice with Two Arrays within a loop
Select or Download Code
Re: Using Splice with Two Arrays within a loop
by moritz (Cardinal) on Jun 10, 2013 at 15:45 UTC

    I don't understand your question. First you say I need to remove a specified number of elements from the @_ array at once rather than the one-at-a-time that shift does, which your code does with splice.

    But then you give it the same input as before, and expect the same outcome, even though you changed the code. Why did you even change the code if you don't want it to change? And how do you expect you will ever get more than two elements into @merge_list, when all you do is to create a new variable and assign to elements to it?

      Sorry for not being clear the issue is that the first part of the code is the original code that I have to modify to work using Splice. Since I am a noobie with Perl the bottom code is my attempt which is not working. I need to use splice to make this work as part of my assignment.

        Here is the splice version. Make sure you understand what's going on before you submit to whomever... (there is a twist...)

        #!/usr/bin/perl use strict; use warnings; my @first = qw(Can unlock secret); my @second = qw(you the code?); my @mixed = interleave_words( scalar(@first), @first, @second ); print "Result: @mixed\n"; sub interleave_words { my $count = shift; my @results = splice @_, $count; foreach my $index ( 0 .. $count-1 ) { splice @results, 2*$index, 0, shift; } return @results; }
      Applogies: I have a assignment as follows: "This program can be made both shorter and faster by using a built-in function named splice that will remove a specified number of elements from the @_ array at once, rather than the one-at-a-time that shift does." Using the existing code I need to change it to use splice and have the same exact output. As you can see it is not working. I need some help in this. Thanks

        Be very careful when you ask for "short" code on this website, you might get what you ask for ... ;) like this (meeting your requirement to use splice):

        sub interleave_words { my @results = splice @_, shift; splice @results, 2*$_, 0, shift for 0..@results-1; return @results; }
Re: Using Splice with Two Arrays within a loop
by hbm (Hermit) on Jun 10, 2013 at 15:47 UTC

    You might find it easier by passing references to your arrays:

    #!/usr/bin/perl use strict; use warnings; my @first = qw(Can unlock secret); my @second = qw(you the code?); my @mixed = interleave_words( scalar(@first), \@first, \@second ); print "Result: @mixed\n"; sub interleave_words { my ($count, $first, $second) = @_; my @results; die unless $#$first == $#$second; return map { $$first[$_], $$second[$_] } 0..$count-1; }
      Hi, Sorry to clarify I have an assignment that requires the following to be done: "This program can be made both shorter and faster by using a built-in function named splice that will remove a specified number of elements from the @_ array at once, rather than the one-at-a-time that shift does." As you can see from my output I am doing something wrong. Can someone help me out. I need to use splice to resolve this. Thanks
        You're supposed to split the argument list into two with splice before the loop.
      You might find it easier by passing references to your arrays ...

      But if you're going to do that, you might as well go all the way and dispense with the count argument altogether as mentioned by davido. In fact, this might actually be a good use for prototyping. Of course, if you use a prototype, you just end up with a version of  mesh() that is specialized for two arguments (easily generalized) and does array-size checking, which  mesh() doesn't. Still...

      >perl -wMstrict -le "use List::MoreUtils qw(mesh); use Data::Dump; ;; my @first = qw(Can unlock secret); my @second = qw(you the code?); ;; sub interleave_words (\@\@); ;; my @mixed = interleave_words(@first, @second); print qq{Result: '@mixed'}; ;; sub interleave_words (\@\@) { die 'array sizes differ' unless $#{$_[0]} == $#{$_[1]}; goto &mesh; } ;; my @ra = qw(a b c); my @rb = qw(1 2 ); dd [ mesh @ra, @rb ]; " Result: 'Can you unlock the secret code?' ["a", 1, "b", 2, "c", undef]

      (Note for anonymous OPer: Don't try this at school unless you really understand what's going on!)

Re: Using Splice with Two Arrays within a loop
by davido (Archbishop) on Jun 10, 2013 at 15:52 UTC

    I don't quite understand why you need a different approach to the same goal in your second snippet. I do think it's clever to have passed a count value for the first array as a way of dealing with the fact that Perl flattens lists, but references are built into the language, in part, to deal with that problem more conveniently. Passing a count is so... "C". ;)

    However, if I were doing it, I would just use List::MoreUtils "zip" function (also known as mesh):

    use List::MoreUtils qw( zip ); my @first = qw( can unlock secret ); my @second = qw( you the code? ); my @mixed = zip @first, @second; print "@mixed\n";

    Dave

      Hi,

      Sorry to clarify I have an assignment that requires the following to be done: "This program can be made both shorter and faster by using a built-in function named splice that will remove a specified number of elements from the @_ array at once, rather than the one-at-a-time that shift does." As you can see from my output I am doing something wrong. Can someone help me out. I need to use splice to resolve this.

      Thanks
Re: Using Splice with Two Arrays within a loop
by hdb (Prior) on Jun 10, 2013 at 15:54 UTC

    Your function already exists in module List::MoreUtils.

    use strict; use warnings; use List::MoreUtils qw{ mesh }; my @first = qw(Can unlock secret); my @second = qw(you the code?); my @mixed = mesh @first, @second; print "Result: @mixed\n";

    UPDATE: Again a few seconds too late... davido being faster again!

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (6)
As of 2014-12-28 01:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (177 votes), past polls