Доброго времени суток!
Подскажите, пожалуйста.
Есть скрипт:
#!/usr/bin/perl
use warnings;
use strict;
use v5.10;
my @list_with_duplicates = qw( 1 2 3 4 5 5 5 5 5 5 5 5 10 10 11 12 );
my %uniq = ();
my @unique_elements = grep { !$uniq{$_}++ } @list_with_duplicates;
say 'say join ",", %uniq;';
say join ",", %uniq;
say 'say join ",", keys %uniq;';
say join ",", keys %uniq;
say 'say join ",", @unique_elements;';
say join ",", @unique_elements;
Он выводит значения, которые не являются дубликатами из списка.
По какому принципу здесь отрабатывает фильтр { !$uniq{$_}++ }
?
В описании функции grep
написано, что функция grep
оценивает значение BLOCK или EXPR на предмет совпадения с каждым элементом списка LIST (устанавливая локально значение $_ поочередно равным каждому элементу) и возвращает список значений, составленный из этих элементов, которые удовлетворяют критерию совпадения.
Если я правильно понимаю, то в фильтре, сначала проверяется, есть ли в хэше %uniq
ключ $_
, если нет, то он записывается в хэш, далее переходим к следующему элементу $_
по списку. Если запись успешна, то он добавляется в @unique_elements
. Так как ключ-значение в хэше - это уникальная пара элементов, мы не можем записать ключ в хэш, который и так там уже присутствует.
Не совсем понимаю, для чего используется !
, чтобы отсеять дубликаты? При каком условии срабатывает переход к следующему элементу ++
или переход срабатывает для всего списка, независимо от того, выполнилось условие или нет? Откуда берутся значения values
в хэше %uniq
? Просто они не совпадают с входным списком.
Спасибо за внимание!