Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to iterate through a Perl array

Which is the best implementation(in terms of speed and memory usage) for iterating through a Perl array? Is there any better way? (@Array need not be retained).

Implementation 1

foreach (@Array) {       SubRoutine($_); } 

Implementation 2

while($Element=shift(@Array)) {       SubRoutine($Element); } 

Implementation 3

while(scalar(@Array) !=0) {       $Element=shift(@Array);       SubRoutine($Element); } 

Implementation 4

for my $i (0 .. $#Array) {       SubRoutine($Array[$i]); } 

Implementation 5

map { SubRoutine($_) } @Array ; 
like image 438
Jean Avatar asked May 07 '12 18:05

Jean


People also ask

How do I iterate in Perl?

In each iteration, you can process each element of the list separately. This is why the for loop statement is sometimes referred to as foreach loop. In Perl, the for and foreach loop are interchangeable, therefore, you can use the foreach keyword in where you use the for keyword.

How do I read an array in Perl?

To access a single element of a Perl array, use ($) sign before variable name. You can assume that $ sign represents singular value and @ sign represents plural values. Variable name will be followed by square brackets with index number inside it. Indexing will start with 0 from left side and with -1 from right side.

What does $# mean in Perl?

EDIT: from perldoc perlvar : $# is also used as sigil, which, when prepended on the name of an array, gives the index of the last element in that array.

How does foreach loop work in Perl?

A foreach loop is used to iterate over a list and the variable holds the value of the elements of the list one at a time. It is majorly used when we have a set of data in a list and we want to iterate over the elements of the list instead of iterating over its range.


2 Answers

  • In terms of speed: #1 and #4, but not by much in most instances.

    You could write a benchmark to confirm, but I suspect you'll find #1 and #4 to be slightly faster because the iteration work is done in C instead of Perl, and no needless copying of the array elements occurs. ($_ is aliased to the element in #1, but #2 and #3 actually copy the scalars from the array.)

    #5 might be similar.

  • In terms memory usage: They're all the same except for #5.

    for (@a) is special-cased to avoid flattening the array. The loop iterates over the indexes of the array.

  • In terms of readability: #1.

  • In terms of flexibility: #1/#4 and #5.

    #2 does not support elements that are false. #2 and #3 are destructive.

like image 96
ikegami Avatar answered Sep 19 '22 03:09

ikegami


If you only care about the elements of @Array, use:

for my $el (@Array) { # ... } 

or

If the indices matter, use:

for my $i (0 .. $#Array) { # ... } 

Or, as of perl 5.12.1, you can use:

while (my ($i, $el) = each @Array) { # ... } 

If you need both the element and its index in the body of the loop, I would expect using each to be the fastest, but then you'll be giving up compatibility with pre-5.12.1 perls.

Some other pattern than these might be appropriate under certain circumstances.

like image 43
Sinan Ünür Avatar answered Sep 21 '22 03:09

Sinan Ünür