Ответ 1
use List::MoreUtils qw/ uniq /;
my @unique = uniq @faculty;
foreach ( @unique ) {
print $_, "\n";
}
Я вставляю элементы в массив во время инструкции while. Каждый элемент является именем учителя. В конце концов заканчивается дублирование имен учителей в массиве, когда цикл завершается. Иногда они не находятся рядом друг с другом в массиве, иногда они есть.
Как я могу напечатать только уникальные значения в этом массиве после того, как он закончил получать значения, введенные в него? Без необходимости анализировать весь массив каждый раз, когда я хочу напечатать элемент.
Получает код после того, как все было перенесено в массив:
$faculty_len = @faculty;
$i=0;
while ($i != $faculty_len)
{
printf $fh '"'.$faculty[$i].'"';
$i++;
}
use List::MoreUtils qw/ uniq /;
my @unique = uniq @faculty;
foreach ( @unique ) {
print $_, "\n";
}
Лучше всего использовать встроенный инструмент (в основном), например uniq (как описано innaM).
Если у вас нет возможности использовать uniq и вы хотите сохранить порядок, вы можете использовать grep для имитации этого.
my %seen;
my @unique = grep { ! $seen{$_}++ } @faculty;
# printing, etc.
Это сначала дает вам хэш, где каждый ключ является каждой записью. Затем вы перебираете каждый элемент, подсчитываете, сколько из них есть, и добавляете первый. (Обновлено с комментариями brian d foy)
Я предлагаю вставить его в хэш. например:
my %faculty_hash = ();
foreach my $facs (@faculty) {
$faculty_hash{$facs} = 1;
}
my @faculty_unique = keys(%faculty_hash);
@array1 = ("abc", "def", "abc", "def", "abc", "def", "abc", "def", "xyz");
@array1 = grep { ! $seen{ $_ }++ } @array1;
print "@array1\n";
На этот вопрос отвечает множество решений в perldoc. Просто введите в командной строке:
perldoc -q duplicate
Обратите внимание: некоторые ответы, содержащие хэш, изменят порядок массива. Хэши не имеют никакого порядка, поэтому получение ключей или значений сделает список с заказом undefined.
Это не относится к grep { ! $seen{$_}++ } @faculty
Это одна команда liner для печати уникальных строк, чтобы она появилась.
perl -ne '$seen{$_}++ || print $_' fileWithDuplicateValues
Я только что нашел избитый 3 лайнер, наслаждаюсь
my %uniq;
undef @uniq(@non_uniq_array);
my @uniq_array = keys %uniq;
Еще один способ сделать это полезен, только если вам не нужен порядок:
my %hash;
@hash{@faculty}=1;
my @unique=keys %hash;
Если вы хотите избежать объявления новой переменной, вы можете использовать недооцененную глобальную переменную % _
@_{@faculty}=1;
my @unique=keys %_;
Если вам нужно обработать список факультетов любым способом, карта над массивом, преобразованная в хэш для коалесцирования ключей, а затем сортировка ключей - это еще один хороший способ:
my @deduped = sort keys %{{ map { /.*/? ($_,1):() } @faculty }};
print join("\n", @deduped)."\n";
Вы обрабатываете список, изменяя регулярное выражение /.*/
для выбора или синтаксического анализа и захвата соответственно, и вы можете выводить один или несколько мутированных, не уникальных ключей за проход, делая ($_,1):()
произвольно сложным.
Если вам нужно изменить данные в полете с помощью регулярного выражения подстановки, скажем, чтобы удалить точки из имен (s/\.//g
), тогда подстановка в соответствии с приведенным выше шаблоном будет мутировать исходный массив @faculty
из-за $_
сглаживание. Вы можете обойти сглаживание $_
, сделав анонимную копию массива @faculty
(см. Так называемый оператор "детская тележка" )
my @deduped = sort keys %{{ map {/.*/? do{s/\.//g; ($_,1)}:()} @{[ @faculty ]} }};
print join("\n", @deduped)."\n";
print "Unmolested array:\n".join("\n", @faculty)."\n";
В более поздних версиях Perl вы можете передать keys
hashref, и вы можете использовать неразрушающую замену:
my @deduped = sort keys { map { /.*/? (s/\.//gr,1):() } @faculty };
В противном случае предпочтительными могут быть решения grep
или $seen[$_]++
в другом месте.