tags:

views:

458

answers:

4

What's the best way to get the last N elements of a Perl array?

If the array has less than N, I don't want a bunch of undefs in the return value.

+5  A: 

I think what you want is called a slice.

siukurnin
A: 

my $size = (scalar @list) - 1; my @newList = @list[$size-$n..$size];

Tim Howland
Doesn't work. You need the .. sigil, not comma, and $size is too large by one.
chaos
you're right, too much time in groovy- I'll edit to match
Tim Howland
May as well just say $#list like Nathan instead of putting scalar(@list) - 1 in a variable.
chaos
I thought about that- since the OP was new to perl, I thought it would be better to avoid the $# construction, in favor of the more straightforward scalar call- I remember hating all the wacky special variables when I was getting started.
Tim Howland
Who said I'm new to Perl?
mike
+15  A: 
@last_n = @source[-$n..-1];

If you require no undefs, then:

@last_n = $n >= @source ? @source : @source[-$n..-1];
chaos
That doesn't work if @source has fewer than $n items.
mike
It work okay. undefs go into @last_n in the positions for which @source has no values, which is correct for some not-entirely-unreasonable semantics of what it means to "take the last N elements".
chaos
oh, I've never used negative subscripts like that, I learned something today!
Nathan
That's pretty clever!
Schwern
@Chaos: I'm putting this here since you wouldn't see a comment on the main post. What's with all the scrubbing and polishing of old, answered questions lately? You've got too much rep to be looking for more (and I know it's not your style). Bored at work? :)
Telemachus
What's wrong with improving your answers?
brian d foy
A: 
@a = (a .. z);
@last_five = @a[ $#a - 4 .. $#a ];
say join " ", @last_five;

outputs:

v w x y z

Nathan