Cómo obtener los elementos únicos de la lista de Perl

La tarea. En el programa en el lenguaje de programación Perl, hay una lista. En la lista hay cadenas y números. Es necesario obtener valores únicos de esta lista.

La solución mediante el uso de la función de uniq de la biblioteca de List::Util

La forma más simple para resolver esta tarea es utilizar la función de uniq de la biblioteca de List::Util. He aquí un ejemplo de código:

▶ Run
#!/usr/bin/perl

use List::Util qw(uniq);
use Data::Dumper;

my @arr = uniq('one', 'one', 'b', 'one', 'b', 4);

print Dumper \@arr;

Si guarda el texto en un archivo script.pl, para luego ejecutar en la consola de perl script.pl, en la pantalla aparecerá:

$VAR1 = [
          'one',
          'b',
          4
        ];

La función de uniq mantiene el orden de los elementos y ella funciona correctamente si en la lista hay undef.

Este código funcionará a partir de la versión de Perl 5.26. En versiones anteriores de Perl contiene la versión de la biblioteca List::Util en la que todavía no hay ninguna función de uniq. Así que para utilizar esta solución debe actualizar el Perl, o poner la nueva versión de la biblioteca List::Util.

La documentación oficial

He aquí un fragmento de la salida del comando perldoc List::Util sobre la función de uniq:

  uniq
        my @subset = uniq @values

    *Since version 1.45.*

    Filters a list of values to remove subsequent duplicates, as judged by a
    DWIM-ish string equality or "undef" test. Preserves the order of unique
    elements, and retains the first value of any duplicate set.

        my $count = uniq @values

    In scalar context, returns the number of elements that would have been
    returned as a list.

    The "undef" value is treated by this function as distinct from the empty
    string, and no warning will be produced. It is left as-is in the
    returned list. Subsequent "undef" values are still considered identical
    to the first, and will be removed.

Propia decisión

Simplemente usted mismo escribir una versión simplificada de la función de uniq de la biblioteca de List::Util:

▶ Run
#!/usr/bin/perl

use Data::Dumper;

sub uniq {
     my (@values) = @_;

     my %h = map {$_ => 1} @values;

     return keys %h;
}

my @arr = uniq('one', 'one', 'b', 'one', 'b', 4);

print Dumper \@arr;

Este código inmediatamente funciona en cualquier versión de Perl. Aquí hay tres líneas de sabi uniq:

  • my (@values) = @_; — colocó los argumentos que se transfieren a sabu en la variable @values
  • my %h = map {$_ => 1} @values; — para cada elemento de @values creado una lista de dos elementos — el original de un elemento y la unidad, y todas las listas se han fusionado en una lista y se apropió de esta lista хешу. El hash es un desordenado conjunto de pares clave-valor. Una clave puede ser un único valor. Gracias a esta propiedad de hash se limpian todas las tomas.
  • return keys %h; — devolvieron la lista sólo se compone de las claves hash

Pero en comparación con la función de uniq de la biblioteca de List::Util este código tiene sus desventajas:

  • nuestra función uniq devuelve los elementos en el orden que desee. Diferentes ejecuciones del mismo código dará lugar a resultados diferentes (el valor que devuelve la función uniq serán los mismos, pero este es el orden en el que se encuentran es diferente)
  • nuestra función no funciona si en la lista hay undef. Utilizamos todos los valores de la lista como una de las claves hash. Y undef no puede ser la clave en хеше. Cuando intenta utilizar undef como la clave será la advertencia y se utiliza una cadena vacía en lugar de undef.

Otros articulos