Come ottenere gli elementi unici di Perl elenco

Il compito. In programma nel linguaggio di programmazione Perl c'è una lista. Nella lista ci sono stringhe e numeri. Bisogno di ottenere i valori unici di questa lista.

La decisione con la funzione uniq di libreria List::Util

Il modo più semplice per risolvere questo problema è quello di utilizzare la funzione uniq dalla libreria List::Util. Ecco un esempio di codice:

▶ Run
#!/usr/bin/perl

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

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

print Dumper \@arr;

Se si salva il testo in un file script.pl, e poi eseguire in console perl script.pl, sullo schermo viene visualizzato:

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

Funzione uniq mantiene l'ordine degli elementi e lei funziona correttamente se nella lista ci sono undef.

Questo codice funziona a partire dalla versione di Perl 5.26. Nelle precedenti versioni di Perl contiene la versione della libreria List::Util in cui ancora non esiste una funzione uniq. Quindi per utilizzare questa soluzione è necessario aggiornare il Perl, o mettere una versione più recente libreria List::Util.

La documentazione ufficiale di

Ecco un frammento di output del comando perldoc List::Util pro la funzione 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.

Propria decisione

Basta scrivere la propria versione semplificata funzione uniq di libreria 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;

Questo codice subito funziona su qualsiasi versione di Perl. Ecco tre righe di sabi uniq:

  • my (@values) = @_; — messo gli argomenti, che sono trasmessi in sabu in una variabile @values
  • my %h = map {$_ => 1} @values; — per ogni elemento di @values creato una lista di due elementi — elemento primordiale e l'unità, e tutte le liste hanno unito in un unico elenco e classificano questo elenco хешу. Hash è un insieme non ordinato di coppie chiave-valore. Per una chiave può essere solo un valore. Grazie a questa proprietà hash vengono pulite tutti i duplicati.
  • return keys %h; — riportato un elenco comprendente solo le chiavi di hash

Ma rispetto alla funzione di uniq dalla libreria List::Util di questo codice ci sono svantaggi:

  • la nostra funzione uniq restituisce gli elementi in ordine casuale. Diverse esecuzioni dello stesso codice porterà a risultati diversi (i valori che restituisce la funzione uniq saranno gli stessi, ma ecco l'ordine in cui sono situati sarà diverso)
  • la nostra funzione non funziona correttamente se nella lista ci sono undef. Usiamo tutti i valori da un elenco di come chiavi di hash. E undef non può essere la chiave di хеше. Quando si tenta di utilizzare undef come chiave sarà un avviso e verrà utilizzata una stringa vuota invece undef.

Altri articoli