Есть ли преимущество использования ключей @array вместо массива 0 .. $ #? - PullRequest
6 голосов
/ 08 августа 2011

Я был очень удивлен, обнаружив, что функция keys успешно работает с массивами:

keys HASH
keys ARRAY
keys EXPR

Возвращает список, состоящий из всех ключей именованного хэшаили индексы массива.(В скалярном контексте возвращает число ключей или индексов.)

Есть ли преимущество в использовании keys @array вместо 0 .. $#array в отношении использования памяти, скорости и т. Д., Илипричины для этой функциональности больше исторического происхождения?

Видя, что keys @array поддерживает до $[ модификации, я предполагаю, что это исторически:

$ 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

Ответы [ 4 ]

4 голосов
/ 08 августа 2011

Я думаю, Марк отчасти прав. Чего ему не хватает, так это того, что каждый теперь работает с массивом, и, подобно каждому с хешами, каждый с массивами возвращает два элемента при каждом вызове. Где each% хэш возвращает ключ и значение, each @array также возвращает ключ (индекс) и значение.

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

Спасибо Zaid за вопрос и jmcnamara за то, что подняли его на CB perlmonks. Я не видел этого раньше - я часто просматривал массив и хотел знать, по какому индексу я нахожусь. Это лучше, чем ручное управление некоторой переменной $i, созданной вне цикла и увеличенной внутри, так как я ожидаю, что continue, redo и т. Д. Выживут лучше.

Итак, поскольку теперь мы можем использовать each для массивов, нам нужно иметь возможность сбросить этот итератор, и, таким образом, мы имеем keys.

3 голосов
/ 08 августа 2011

Ссылка, которую вы предоставили, на самом деле имеет одну важную причину, которую вы могли бы использовать / не использовать keys:

В качестве побочного эффекта, вызывая keys () сбрасывает внутренний интегратор HASH или ARRAY (увидеть каждый).В частности, вызов keys () в пустом контексте сбрасывает итератор без дополнительных затрат.

Это приведет к сбросу each в начало массива.Использование keys и each с массивами может быть важно, если они когда-либо изначально поддерживают разреженные массивы в качестве реального типа данных.join в perl, я не могу вспомнить, когда в последний раз я использовал 0..$#array.

2 голосов
/ 08 августа 2011

Я действительно думаю, что вы ответили на свой вопрос: он возвращает действительные индексы массива, независимо от того, какое значение вы установили для $[.Таким образом, с точки зрения общности (особенно для использования библиотеки), это более предпочтительно.

Версия Perl, которую я имею (5.10.1), не поддерживает использование keys с массивами, поэтому она может 'по историческим причинам.

0 голосов
/ 08 августа 2011

Хорошо, в вашем примере вы помещаете их в список; Итак, в контексте списка

keys @array будет заменено всеми элементами массива тогда как 0 .. $#array будет делать то же самое, но как нарезка массива; Итак, вместо $array[0 .. $#array] вы также можете упомянуть $array[0 .. (some specific index)]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...