http://qs321.pair.com?node_id=220171

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

I have an array and I would like to print the last few elements (most recent) to the screen. I have put together the following code to make this happen:
open (FILE, "$record") or die 'can\'t open record page: $!'; my @record =<FILE>; close FILE; my @record = reverse @record; my @record1 = ($record[0], $record[1], $record[2], $record[3], $re +cord[4], $record[5], $record[6], $record[7], $record[8], $record[9]); + my $record1 = join "<br>", @record1;
($record1 is then used in conjunction with HTML::Template.)

This is obviously not very perl so I thought I'd get some input from anyone kind enough to help me as to the alternatives I might have used to do the same thing.

One of the things I did try was the following:
@record = reverse @record; my @record1; my $count = 0; while (($count < 5) && (my $line = @record)) { push (@record1, $line); $count += 1; } print "@record1";
This produced some very odd results so it's obvious that just as in the "Hitchhiker's Guide" I don't understand the question I asked! If someone does and could explain, that would be great.

Thanks very much.

Replies are listed 'Best First'.
Re: Printing the last few elements of an array.
by rob_au (Abbot) on Dec 16, 2002 at 11:33 UTC
    There is a very nifty trick documented in perldata regarding the referencing of elements of arrays - Where the subscript referenced in an array is negative, the element returned is counted from the end of the array. As such, the last element of the array could be returned using the syntax of $record[ -1 ], thereby alleviating the requirement to reverse the array elements prior to reference.

    Furthermore, multiple array elements can be returned using an array slice - For example, the following will return the last three elements of the array:

    my ( $third_last, $second_last, $last ) = @record[ -3, -2, -1 ];

    Again, this syntax and behaviour is documented in perldata.

    Additionally, depending upon the size of the file being read into memory, the modules Tie::File and File::ReadBackwards may also be of interest.

     

    perl -le 'print+unpack("N",pack("B32","00000000000000000000000111111011"))'

      Thanks for your reply, rob_au - I posted to try and broaden my (minute) knowledge base so this is what I needed!
Re: Printing the last few elements of an array.
by thinker (Parson) on Dec 16, 2002 at 11:40 UTC
    Hi jonnyfolk,

    one way would be
    #!/usr/bin/perl -w use strict; my $record='DATA'; open (FILE, "$record") or die $!; my @record = reverse <FILE>; print "@record[0..9]";

    cheers

    thinker
      Thanks, thinker. Quick'n'easy - just the job!
Re: Printing the last few elements of an array.
by Molt (Chaplain) on Dec 16, 2002 at 14:59 UTC

    You can, of course, merge the two approaches given above as demonstrated in this little piece of code here.

    #!/usr/bin/perl use strict; use warnings; my @array = (1,2,3,4,5,6,7,8,9,10); print "$_\n" foreach @array[-3..-1];

    I'd also like to thank rob_au and thinker since without seeing their posts next to one another I'd have not realised this nice simple way to do things- guess the random linking of ideas is one of the good things about this site. ++'s to both of you.

Re: Printing the last few elements of an array.
by dakkar (Hermit) on Dec 16, 2002 at 17:29 UTC

    About 'the question you asked' in the second snippet: you got out a number, repeated 5 times, right?

    This is because you wrote $line=@record, which means: assign to $line the number of elements in the array @record.

    This happens because assigning to a scalar variables sets scalar context for the right-hand side of the assignment, and an array in scalar context evaluates to its lenght.

    -- 
            dakkar - Mobilis in mobile
    
      Thanks dakkar - now I understand! Is there any way I could have phrased that to make the $count mechanism work?
        @record=reverse @record; my @record1; my $count=0; my $line; while (($count<5) && ($line=$record[$count])) { push @record1,$line; $count++ } @record1=reverse @record1; print join ',',@record1;

        The last reverse is to get the elements in the original order.

        Just promise me you won't really use this version, please? ;-)))

        -- 
                dakkar - Mobilis in mobile
        
Re: Printing the last few elements of an array.
by tachyon (Chancellor) on Dec 17, 2002 at 10:58 UTC
    # Yet Another Way To Do It @ary = qw ( 1 2 3 4 5 6 7 8 ); print pop @ary, "<br>\n" for 1..3; # or print "$_<br>\n" for reverse @ary[-3..-1];

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print