У меня есть массив в Perl:
my @my_array = ("one","two","three","two","three");
Как мне удалить дубликаты из массива?
perl
arrays
unique
duplicates
Дэвид
источник
источник
my
лексическое в этом смысле, так что все в порядке. При этом, возможно, можно было бы выбрать более описательное имя переменной.$::a
и$::b
не так ли?sub uniq { my %seen; grep !$seen{$_}++, @_ }
это лучшая реализация, поскольку она сохраняет порядок без затрат. Или даже лучше, используйте тот из List :: MoreUtils.Документация Perl поставляется с хорошей коллекцией часто задаваемых вопросов. Ваш вопрос часто задают:
Ответ, скопированный и вставленный из вывода команды выше, появляется ниже:
источник
Список установки :: MoreUtils из CPAN
Тогда в вашем коде:
источник
@dup_list
должен быть внутриuniq
звонка, а не@dups
Мой обычный способ сделать это:
Если вы используете хеш и добавляете элементы в хеш. Вы также можете узнать, сколько раз каждый элемент появляется в списке.
источник
foreach
цикла:@unique{@myarray}=()
Переменная @array - это список с дублирующимися элементами.
источник
Может быть сделано с простым Perl одним вкладышем.
Блок PFM делает это:
Данные в @in поступают в MAP. MAP создает анонимный хэш. Ключи извлекаются из хеша и передаются в @out
источник
Последний был довольно хорош. Я бы просто немного подправил:
Я думаю, что это, вероятно, самый читаемый способ сделать это.
источник
Способ 1: использовать хеш
Логика: хеш может иметь только уникальные ключи, поэтому итерируйте по массиву, присваивайте любое значение каждому элементу массива, сохраняя элемент в качестве ключа этого хеша. Вернуть ключи хеша, это ваш уникальный массив.
Метод 2: Расширение метода 1 для повторного использования
Лучше создать подпрограмму, если мы должны использовать эту функцию несколько раз в нашем коде.
Способ 3: использовать модуль
List::MoreUtils
источник
Предыдущие ответы в значительной степени суммируют возможные пути выполнения этой задачи.
Тем не менее, я предлагаю модификацию для тех , кто не заботится о подсчете дубликатов, но сделать заботу о порядке.
Обратите внимание, что ранее предложенные
grep !$seen{$_}++ ...
приращения$seen{$_}
перед отрицанием, поэтому приращение происходит независимо от того, было ли оно уже%seen
или нет. Выше, однако, короткие замыкания, когда$record{$_}
это правда, оставляя то, что было услышано однажды «вне%record
».Вы также можете пойти на эту нелепость, которая использует преимущества автовивификации и наличия хеш-ключей:
Это, однако, может привести к некоторой путанице.
И если вас не интересует ни порядок, ни количество дубликатов, вы можете сделать еще один взлом, используя хэш-фрагменты и трюк, о котором я только что упомянул:
источник
sub uniq{ my %seen; undef @seen{@_}; keys %seen; }
аккуратно.Попробуйте, кажется, что для правильной работы функции uniq нужен отсортированный список.
источник
Используя концепцию уникальных хеш-ключей:
Выход: acbd
источник