¿Cómo elimino elementos duplicados de una matriz en Perl?

Tengo una matriz en Perl:

my @my_array = ("one","two","three","two","three"); 

¿Cómo elimino los duplicados de la matriz?

    Puedes hacer algo como esto como se demuestra en perlfaq4 :

     sub uniq { my %seen; grep !$seen{$_}++, @_; } my @array = qw(one two three two three); my @filtered = uniq(@array); print "@filtered\n"; 

    Productos:

     one two three 

    Si quieres usar un módulo, prueba la función uniq desde List::MoreUtils

    La documentación de Perl viene con una buena colección de preguntas frecuentes. Tu pregunta es frecuente:

     % perldoc -q duplicate 

    La respuesta, copiar y pegar desde el resultado del comando anterior, aparece a continuación:

      Se encuentra en /usr/local/lib/perl5/5.10.0/pods/perlfaq4.pod
      ¿Cómo puedo eliminar elementos duplicados de una lista o matriz?
        (contribuido por brian d foy)
    
        Use un hash  Cuando piense en las palabras "único" o "duplicado", piense
        "teclas hash".
    
        Si no te importa el orden de los elementos, podrías simplemente
        crea el hash y luego extrae las claves.  No es importante cómo
        cree ese hash: simplemente use las "claves" para obtener los elementos únicos.
    
            my% hash = map {$ _, 1} @array;
            # o una porción hash: @hash {@array} = ();
            # o un foreach: $ hash {$ _} = 1 foreach (@array);
    
            my @unique = keys% hash;
    
        Si desea usar un módulo, intente con la función "uniq"
        "List :: MoreUtils".  En el contexto de la lista, devuelve los elementos únicos,
        preservando su orden en la lista.  En contexto escalar, devuelve el
        cantidad de elementos únicos
    
            use List :: MoreUtils qw (uniq);
    
            mi @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
    
        También puede ir a través de cada elemento y omitir los que ha visto
        antes de.  Use un hash para realizar un seguimiento.  La primera vez que el ciclo ve una
        elemento, ese elemento no tiene clave en% Visto.  La statement "siguiente" crea
        la tecla e inmediatamente usa su valor, que es "undef", entonces el ciclo
        continúa con el "empuje" e incrementa el valor de esa tecla.  El siguiente
        vez que el ciclo ve ese mismo elemento, su clave existe en el hash y
        el valor de esa clave es verdadero (ya que no es 0 o "undef"), por lo que
        Luego se salta esa iteración y el ciclo pasa al siguiente elemento.
    
            mi @unique = ();
            mi% visto = ();
    
            foreach my $ elem (@array)
            {
              siguiente si $ seen {$ elem} ++;
              push @unique, $ elem;
            }
    
        Puedes escribir esto más brevemente usando un grep, que hace lo mismo
        cosa.
    
            mi% visto = ();
            mi @unique = grep {!  $ seen {$ _} ++} @array;
    

    Instalar List :: MoreUtils de CPAN

    Luego en tu código:

     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); 

    Mi forma habitual de hacer esto es:

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

    Si usa un hash y agrega los elementos al hash. También tiene la ventaja de saber cuántas veces aparece cada elemento en la lista.

    Se puede hacer con un simple trazador de líneas de Perl.

     my @in=qw(1 3 4 6 2 4 3 2 6 3 2 3 4 4 3 2 5 5 32 3); #Sample data my @out=keys %{{ map{$_=>1}@in}}; # Perform PFM print join ' ', sort{$a< =>$b} @out;# Print data back out sorted and in order. 

    El bloque PFM hace esto:

    Los datos en @in se introducen en MAP. MAP crea un hash anónimo. Las claves se extraen del hash y se envían a @out

    La variable @array es la lista con elementos duplicados

     %seen=(); @unique = grep { ! $seen{$_} ++ } @array; 

    Ese último fue bastante bueno. Lo retocaré un poco:

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

    Creo que esta es probablemente la forma más legible de hacerlo.

    Método 1: Usa un hash

    Lógica: Un hash puede tener solo claves únicas, así que itere sobre el conjunto, asigne cualquier valor a cada elemento de un conjunto, manteniendo el elemento como la clave del mismo. Devuelve las claves del hash, es tu matriz única.

     my @unique = keys {map {$_ => 1} @array}; 

    Método 2: Extensión del método 1 para reutilización

    Es mejor hacer una subrutina si se supone que debemos usar esta funcionalidad varias veces en nuestro código.

     sub get_unique { my %seen; grep !$seen{$_}++, @_; } my @unique = get_unique(@array); 

    Método 3: Use la List::MoreUtils módulos List::MoreUtils

     use List::MoreUtils qw(uniq); my @unique = uniq(@array); 

    Pruebe esto, parece que la función uniq necesita una lista ordenada para funcionar correctamente.

     use strict; # Helper function to remove duplicates in a list. sub uniq { my %seen; grep !$seen{$_}++, @_; } my @teststrings = ("one", "two", "three", "one"); my @filtered = uniq @teststrings; print "uniq: @filtered\n"; my @sorted = sort @teststrings; print "sort: @sorted\n"; my @sortedfiltered = uniq sort @teststrings; print "uniq sort : @sortedfiltered\n"; 

    Usando el concepto de teclas hash únicas:

     my @array = ("a","b","c","b","a","d","c","a","d"); my %hash = map { $_ => 1 } @array; my @unique = keys %hash; print "@unique","\n"; 

    Salida: acbd