Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any advantage to using keys @array instead of 0 .. $#array?

Tags:

perl

I was quite surprised to find that the keys function happily works with arrays:

keys HASH
keys ARRAY
keys EXPR

Returns a list consisting of all the keys of the named hash, or the indices of an array. (In scalar context, returns the number of keys or indices.)

Is there any benefit in using keys @array instead of 0 .. $#array with respect to memory usage, speed, etc., or are the reasons for this functionality more of a historic origin?

Seeing that keys @array holds up to $[ modification, I'm guessing it's historic :

$ perl -Mstrict -wE 'local $[=4; my @array="a".."z"; say join ",", keys @array;'
Use of assignment to $[ is deprecated at -e line 1.
4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29
like image 580
Zaid Avatar asked Aug 08 '11 14:08

Zaid


2 Answers

Mark has it partly right, I think. What he's missing is that each now works on an array, and, like the each with hashes, each with arrays returns two items on each call. Where each %hash returns key and value, each @array also returns key (index) and value.

while (my ($idx, $val) = each @array)
{
  if ($idx > 0 && $array[$idx-1] eq $val)
  {
     print "Duplicate indexes: ", $idx-1, "/", $idx, "\n";
  }
}

Thanks to Zaid for asking, and jmcnamara for bringing it up on perlmonks' CB. I didn't see this before - I've often looped through an array and wanted to know what index I'm at. This is waaaay better than manually manipulating some $i variable created outside of a loop and incremented inside, as I expect that continue, redo, etc., will survive this better.

So, because we can now use each on arrays, we need to be able to reset that iterator, and thus we have keys.

like image 118
Tanktalus Avatar answered Nov 08 '22 17:11

Tanktalus


The link you provided actually has one important reason you might use/not use keys:

As a side effect, calling keys() resets the internal interator of the HASH or ARRAY (see each). In particular, calling keys() in void context resets the iterator with no other overhead.

That would cause each to reset to the beginning of the array. Using keys and each with arrays might be important if they ever natively support sparse arrays as a real data-type.

All that said, with so many array-aware language constructs like foreach and join in perl, I can't remember the last time I used 0..$#array.

like image 29
Mark Avatar answered Nov 08 '22 18:11

Mark