All other things being equal, I'd use splice, the code is much more readable:

my @all_but_one = splice( @$arrayref, 0, -1 );

As an added bonus, it's also faster:

#! /usr/bin/perl -w use strict; use Benchmark qw/cmpthese/; my @x = qw/a b c/; sub with_splice { my $aref = shift; splice( @$aref, 0, -1 ); } sub with_range { my $aref = shift; @{$aref}[0 .. ($#{$aref} - 1)] } print 'range ', join( ' ' => with_range(\@x) ), "\n"; print 'splice ', join( ' ' => with_splice(\@x) ), "\n"; my @z = 0 .. 100_000; cmpthese( shift || 2_000_000, { short_splice => sub { with_splice(\@x) }, short_range => sub { with_range (\@x) }, } ); cmpthese( shift || 1_000, { long_splice => sub { with_splice(\@z) }, long_range => sub { with_range (\@z) }, } ); __RESULTS__ range a b splice a b Benchmark: timing 2000000 iterations of short_range, short_splice... short_range: 9 wallclock secs ( 7.83 usr + 0.00 sys = 7.83 CPU) @ 2 +55489.02/s (n=2000000) short_splice: 5 wallclock secs ( 5.06 usr + 0.01 sys = 5.07 CPU) @ +394453.00/s (n=2000000) Rate short_range short_splice short_range 255489/s -- -35% short_splice 394453/s 54% -- Benchmark: timing 1000 iterations of long_range, long_splice... long_range: 40 wallclock secs (39.73 usr + 0.02 sys = 39.74 CPU) @ 25 +.16/s (n=1000) long_splice: 0 wallclock secs ( 0.01 usr + 0.00 sys = 0.01 CPU) @ 1 +28000.00/s (n=1000) (warning: too few iterations for a reliable count) Rate long_range long_splice long_range 25.2/s -- -100% long_splice 128000/s 508600% --

As should be obvious (assuming I'm benchmarking the right thing :), the longer the array, the faster the splice.

update: actually, playing around with the code a bit (because arrays with around 100 000 elements are usually few and far between in production code), I reduced the size down to 500 elements, and the splice method shows no degradation, but the range operator does:

enchmark: timing 300000 iterations of short_range, short_splice... short_range: 2 wallclock secs ( 1.16 usr + 0.00 sys = 1.16 CPU) @ 2 +59459.46/s (n=300000) short_splice: 1 wallclock secs ( 0.75 usr + 0.00 sys = 0.75 CPU) @ +400000.00/s (n=300000) Rate short_range short_splice short_range 259459/s -- -35% short_splice 400000/s 54% -- Benchmark: timing 200000 iterations of long_range, long_splice... long_range: 36 wallclock secs (37.30 usr + 0.00 sys = 37.30 CPU) @ 53 +62.38/s (n=200000) long_splice: 0 wallclock secs ( 0.50 usr + 0.00 sys = 0.50 CPU) @ 4 +00000.00/s (n=200000) Rate long_range long_splice long_range 5362/s -- -99% long_splice 400000/s 7359% --

Well, that was fun.


In reply to Re: Trying to slice off all array elements but the last one (use splice) by grinder
in thread Trying to slice off all array elements but the last one by talexb

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.