开发者

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

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,1开发者_JAVA技巧8,19,20,21,22,23,24,25,26,27,28,29


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.


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.


I actually think you've answered your own question: it returns the valid indices of the array, no matter what value you've set for $[. So from a generality point of view (especially for library usage), it's more preferred.

The version of Perl I have (5.10.1) doesn't support using keys with arrays, so it can't be for historic reasons.


Well in your example, you are putting them in a list; So, in a list context

keys @array will be replaced with all elements of array whereas 0 .. $#array will do the same but as array slicing; So, instead $array[0 .. $#array] you can also mention $array[0 .. (some specific index)]

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜