Проверка наличия ключа в хэше

Проблема

Требуется узнать, содержит ли хэш конкретный ключ независимо от ассоциированного с ним значения.

Решение

Воспользуйтесь функцией exists:
# Содержит ли %ХЭШ ключ $КЛЮЧ?
if (exists($XЭШ{$КЛЮЧ}))   {
  # Ключ существует
} else {
    # Ключ не существует
  }

Комментарий

В следующем фрагменте функция exists проверяет, присутствует ли ключ хэше %food_color:
foreach $name ("Banana", "Martini") {
  if (exists $food_color{$name}) {
    print "$name is a food.\n";
  } else {
    print "$name is a drink.\n";
    }
}
Banana is a food.
Martini is a drink.
Функция exists проверяет только наличие ключа в хэше. Она не сообщае об ассоциированном значении, определено ли оно, истинно или ложно. На первый взгляд кажется, что отличия несущественны. Однако в действительности проблемы такого рода плодятся быстро, как кролики. Возьмем следующий фрагмент:
%age = ();
$age {"Toddler"} = 3;
$age {"Unborn"} = 0;
$age {"Phantasm"} = undef;
foreach $thing ("Toddler", "Unborn", "Phantasm", "Relic") {
  print "$thing: ";
  print "Exists " if exists $age{$thing};
  print "Defined " if defined $age{thing};
  print  "True " if $age{$thing};
  print "\n";
}
Toddler: Exists Defined True
Unborn:  Exists Defined
Phantasm: Exists
Relic:
Элемент $age{"Toddler"} проходит все три проверки — существования, определенности и истинности. Он существует, потому что мы присвоили ключу "Toddler" значение в хэше. Он определен, потому что значение не равно undef. Наконец, он истинен, потому что присвоенная величина не является одним из ложных значений Perl.
Элемент $age{"Unborn"} проходит только проверки существования и определенности. Он существует, потому что ключу "Unborn" было присвоено значение в хэше, и определен, потому что это значение не равно undef. Однако он не является истинным, потому что 0 интерпретируется в Perl как одна из ложных величин.
Элемент $age{"Phantasm"} проходит только проверку существования. Он существует, потому что ключу "Phantasm" было присвоено значение в хэше. Поскольку это значение представляет собой undef, проверка определенности не работает. Так как undef также считается в Perl одним из ложных значений, проверка истинности тоже не работает.
Наконец, $age{"Relic"} не проходит ни одну из проверок. Значение для "Relic" не заносилось в хэш, поэтому проверка на существование завершается неудачей. Из-за отсутствия ассоциированного значения попытка обратиться к $age{"Relic" } дает undef. Как мы знаем из примера с "Phantasm", undef не проходит проверки определенности и истинности.
Иногда undef полезно сохранить в хэше. Это означает: «такой ключ встречается, но с ним не связано никакого полезного значения». Например, рассмотрим программу, которая определяет размер файлов из переданного списка. Следующий фрагмент пытается пропускать файлы, которые уже встречались в списке, однако это не касается файлов нулевой длины и встречавшихся ранее несуществующих файлов:
%name = ();
while (<>) {
  chomp;
  next if $name {$_};     # НЕВЕРНО
  $name{$_} = -s $_;
}
Замена неправильной строки следующим вызовом exists позволяет пропускать нулевые и несуществующие файлы:
next if exists $name{$_};
В самом первом примере предполагается, что все, что не является едой (food) относится к напиткам (drink). В реальном мире подобные допущения весьма опасны.

См. также

Описание функций exists и defined



2013-09-10 17:05:19

Proverte kod v komentariyah gde pro list tam oshibki detskie




Оставить комментарий:
Ваше Имя:
Email:
Антибот: *  
Ваш комментарий: