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)]
精彩评论