Как удалить повторяющиеся элементы из массива в Perl?

Лучший способ заключается в выборе вашего языка при создании обертки модели для ваших объектов, попробуйте выполнить метод save () через набор полей, которые вы будете искать, которые также индексируются; эти группы полей должны иметь строчные копии, которые затем используются для поиска.

Каждый раз, когда объект сохраняется снова, нижние значения затем проверяются и обновляются с любыми изменениями основных свойств. Это сделает так, чтобы вы могли эффективно искать, но скрыть дополнительную работу, необходимую для обновления полей lc каждый раз.

В нижнем регистре могут быть хранилище объектов с ключом: значение или просто имя поля с префикс lc_. Я использую второй, чтобы упростить запрос (запросы на глубинные объекты могут иногда заблуждаться).

Примечание: вы хотите индексировать поля lc_, а не основные поля, на которых они основаны.

148
задан Сухой27 25 December 2014 в 19:57
поделиться

5 ответов

Можно сделать что-то вроде этого, как продемонстрировано в perlfaq4:

sub uniq {
    my %seen;
    grep !$seen{$_}++, @_;
}

my @array = qw(one two three two three);
my @filtered = uniq(@array);

print "@filtered\n";

Выводы:

one two three

Если Вы хотите использовать модуль, попробуйте uniq функция от List::MoreUtils

161
ответ дан Miller 25 December 2014 в 19:57
поделиться

Установка Список:: MoreUtils от CPAN

Тогда в Вашем коде:

use strict;
use warnings;
use List::MoreUtils qw(uniq);

my @dup_list = qw(1 1 1 2 3 4 4);

my @uniq_list = uniq(@dup_list);
66
ответ дан Coding Minds 25 December 2014 в 19:57
поделиться

Документация Perl идет с хорошим набором часто задаваемых вопросов. Ваш вопрос часто задают:

% perldoc -q duplicate

Ответ, копия и вставляемый от вывода команды выше, появляется ниже:

Found in /usr/local/lib/perl5/5.10.0/pods/perlfaq4.pod
 How can I remove duplicate elements from a list or array?
   (contributed by brian d foy)

   Use a hash. When you think the words "unique" or "duplicated", think
   "hash keys".

   If you don't care about the order of the elements, you could just
   create the hash then extract the keys. It's not important how you
   create that hash: just that you use "keys" to get the unique elements.

       my %hash   = map { $_, 1 } @array;
       # or a hash slice: @hash{ @array } = ();
       # or a foreach: $hash{$_} = 1 foreach ( @array );

       my @unique = keys %hash;

   If you want to use a module, try the "uniq" function from
   "List::MoreUtils". In list context it returns the unique elements,
   preserving their order in the list. In scalar context, it returns the
   number of unique elements.

       use List::MoreUtils qw(uniq);

       my @unique = uniq( 1, 2, 3, 4, 4, 5, 6, 5, 7 ); # 1,2,3,4,5,6,7
       my $unique = uniq( 1, 2, 3, 4, 4, 5, 6, 5, 7 ); # 7

   You can also go through each element and skip the ones you've seen
   before. Use a hash to keep track. The first time the loop sees an
   element, that element has no key in %Seen. The "next" statement creates
   the key and immediately uses its value, which is "undef", so the loop
   continues to the "push" and increments the value for that key. The next
   time the loop sees that same element, its key exists in the hash and
   the value for that key is true (since it's not 0 or "undef"), so the
   next skips that iteration and the loop goes to the next element.

       my @unique = ();
       my %seen   = ();

       foreach my $elem ( @array )
       {
         next if $seen{ $elem }++;
         push @unique, $elem;
       }

   You can write this more briefly using a grep, which does the same
   thing.

       my %seen = ();
       my @unique = grep { ! $seen{ $_ }++ } @array;
119
ответ дан John Siracusa 25 December 2014 в 19:57
поделиться

Мой обычный способ сделать это:

my %unique = ();
foreach my $item (@myarray)
{
    $unique{$item} ++;
}
my @myuniquearray = keys %unique;

, Если Вы используете хеш и добавляете объекты к хешу. У Вас также есть премия знания, сколько раз каждый объект появляется в списке.

22
ответ дан Chankey Pathak 25 December 2014 в 19:57
поделиться

Тот последний был довольно хорош. Я просто настроил бы его немного:

my @arr;
my @uniqarr;

foreach my $var ( @arr ){
  if ( ! grep( /$var/, @uniqarr ) ){
     push( @uniqarr, $var );
  }
}

я думаю, что это - вероятно, самый читаемый способ сделать это.

4
ответ дан jh314 25 December 2014 в 19:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: