Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

my @saved_images = qq(@found_images[0 .. $pics_to_find]); Doesn't work. @saved_images is empty. @found_images is NOT empty.

Please advise me oh wise monks.

All I want to do is crunch down an array to a specific number of elements. I could do it with a foreach loop with the extra array, but I really don't want to do a foreach loop as I know there's a better way.

Maybe someone will suggest splice and show an example?

Replies are listed 'Best First'.
Re: merging arrays
by GrandFather (Saint) on Jun 24, 2006 at 03:55 UTC

    I guess it's not merging that you want so much as slicing You were closeish, but the interpolation was not helping at all. Try this:

    use strict; use warnings; my $pics_to_find = 3; my @found_images = (1, 2, 3, 4, 5); my @saved_images = @found_images[0 .. $pics_to_find - 1]; print "@saved_images";

    Prints:

    1 2 3

    DWIM is Perl's answer to Gödel
      When I went to print that out, it appears as though it indexed every position from the original array into this one. Now it has some 100s of undefined values. I guess it really didn't do as I expected. Maybe I should just do a foreach and do it that way?

        Reduce your code to a small sample that shows the problem and post it.


        DWIM is Perl's answer to Gödel
        That's exactly the expected behaviour. You loop from $a..$n. So you get some value for $a..$n :)
        If you don't want the undefined values, grep for the defined ones:
        my @saved_images = grep { defined $_ } @found_images[0 .. $pics_to_fin +d - 1];
        cheers,
        --shmem
        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: merging arrays
by Samy_rio (Vicar) on Jun 24, 2006 at 03:59 UTC

    Hi Anonymous Monk, It works for me as below:

    use strict; use warnings; my @found_images = qw( hello i am fine); my $pics_to_find = 2; my @saved_images = qq(@found_images[0..$pics_to_find]); #$,="\n"; #print @saved_images; print $saved_images[0]; __END___ OutPut is : hello i am

    Use my @saved_images = @found_images[0..$pics_to_find]; also for crunch the array.

    Updated

    Regards,
    Velusamy R.


    eval"print uc\"\\c$_\""for split'','j)@,/6%@0%2,`e@3!-9v2)/@|6%,53!-9@2~j';

      That doesn't work the way you think it works. Assign to $" to see what's in the array:

      { local $" = ')('; print "(@saved_images)\n"; }

      You really don't need the qq() in there.

Re: merging arrays
by sfink (Deacon) on Jun 24, 2006 at 17:40 UTC
    Understanding slicing will give you a handy general-purpose tool, but you are correct that splice is the right thing for this particular purpose, assuming you don't need the previous contents of @found_images:
    splice(@found_images, $pics_to_find);
    That deletes all images in @found_images starting at the index $pics_to_find and continuing to the end.

    If you don't want to completely lose those discarded images, use

    my @discarded_images = splice(@found_images, $pics_to_find);
    I find it very difficult to remember the syntax of splice. I have typed 'perldoc -f slice' many times. Not that it doesn't make sense: splice is for removing a range of elements from an array and replacing them with a list, with useful default behavior if only parts of the operation are defined. So perhaps logic is enough to figure out the parameters:

    The first parameter is obvious -- it's the array to operate on. Next we need to know the range of elements to remove, so that's obviously a start and length parameter pair. And wouldn't it be nice if you could leave off the length if you wanted the rest of the array? Or if you prefer, what should happen if you leave off that length parameter? The only thing that makes sense is nuking up to the end. Oh, and a negative start argument would be handy too, if you're only concerned with the right end of the array.

    Finally, there's the list of elements to insert into the "spliced" portion of the array. And just one more thing -- you might need to know what the removed elements were, so it would be convenient to return them from the overall call.

    It is my hope that, having typed out that rationale, I will now be able to figure it out on my own without running back to the docs. We'll see how that works...

      I find it very difficult to remember the syntax of splice.

      It might help to realize that splice and substr use the same syntax.

      Arg0: Source (array or string) from which to extract items (elements or chars).
      Arg1: Index of the item from which to start extracting. Negative indexes are relative to the end of the source.
      Arg2: (Optional) Number of items to extract.
      Arg3: (Optional) Items with which to replace the extracted items.

      The difference is that splice is destructive (extracted elements are removed from the source) whereas substr is not (unless the Arg3 is specified).