-+  Associazione
-+  Documenti
 |-  Modern Perl
 |-  Bibliografia
 |-  Articoli
 |-  Talk
 |-  Perlfunc
 |-  F.A.Q.
 |-  F.A.Q. iclp
-+  Eventi
-+  Community
-+  Blog
-+  Link
Corso di Perl



 


indietro

[42] Come posso determinare se un certo elemento è contenuto in una lista o in un array?

(parti di questa risposta sono un contributo di Anno Siegel)

Già sentire la parola "in" è un'indicazione che avreste probabilmente dovuto utilizzare un hash, non una lista o un array, per memorizzare i vostri dati. Gli hash sono progettati per offrire una risposta rapida ed efficiente a questa domanda. Gli array no.

Detto questo, ci sono molti modi per risolvere la questione. Se dovete fare questa operazione molte volte su stringhe arbitrarie, la via più veloce è probabilmente quella di invertire l'array originale e creare un hash le cui chiavi sono gli elementi dell'array.

    @blu = qw/azzurro ceruleo celeste turchese oltremare/;
    %un_blu = ();
    for (@blu) { $un_blu{$_} = 1 }

Ora potete controllare se è $un_blu{$un_colore}. Potrebbe essere stata una buona idea quella di memorizzare i blu in un hash sin dall'inizio.

Se i valori sono tutti interi piccoli, potete usare un semplice array indicizzato. Questo tipo di array utilizzerà meno spazio:

    @primi = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31);
    @un_piccolo_primo = ();
    for (@primi) { $un_piccolo_primo[$_] = 1 }
    # o semplicemente @un_piccolo_primo[@primi] = (1) x @primi;

Ora potete controllare se è $un_piccolo_primo[$un_numero].

Se i valori in questione sono interi anziché stringhe, potete salvare molto spazio utilizzando le stringhe di bit:

    @articoli = ( 1..10, 150..2000, 2017 );
    undef $letti;
    for (@articoli) { vec($letti,$_,1) = 1 }

Ora controllate se vec($letti,$n,1) è vero per un determinato $n.

Questi metodi garantiscono che i test individuali siano eseguiti rapidamente ma richiedono una riorganizzazione dell'originale lista o array. Sono redditizzi solo se dovete testare valori multipli sullo stesso array.

Se ne state testando solo uno, il modulo standard List::Util esporta, a questo scopo, la funzione first. Funziona fermandosi una volta che ha trovato l'elemento. È scritta in C per la velocità ed il suo equivalente in Perl assomiglia a questa subroutine:

	sub first (&@) {
		my $codice = shift;
		foreach (@_) {
			return $_ if &{$codice}();
		}
		undef;
	}

Se la velocità è una cosa di poco interesse, lo stile più diffuso è quello di utilizzare grep in contesto scalare (che restituisce il numero di elementi che hanno verificato la sua condizione) per traversare l'intera lista. Tuttavia, questo ha il sicuro vantaggio di rivelarvi quante corrispondenze ha trovato.

	my $presente = grep $_ eq $qualsiasicosa, @array;

Se in realtà volete estrarre gli elementi che effettuano il match, usate semplicemente grep in contesto di lista.

	my @match = grep $_ eq $qualsiasicosa, @array;

vedi in inglese

AUTORE E COPYRIGHT

Copyright (c) 1997, 1998, 1999, 2000, 2001 Tom Christiansen e Nathan Torkington. Tutti i diritti riservati.

Questa documentazione è libera; puoi ridistribuirla e/o modificarla secondo gli stessi termini applicati al Perl.

Indipendentemente dalle modalitè di distribuzione, tutti gli esempi di codice in questo file sono rilasciati al pubblico dominio. Potete, e siete incoraggiati a farlo, utilizzare il presente codice o qualunque forma derivata da esso nei vostri programmi per divertimento o per profitto. Un semplice commento nel codice che dia riconoscimento alle FAQ sarebbe cortese ma non è obbligatorio.

D:
Progetti e documenti in rilievo
Corso di Perl Progetto pod2it
D:
La ML di Perl.it
mongers@perl.it è la lista ufficiale di Perl Mongers Italia per porre quesiti di tipo tecnico, per rimanere aggiornato su meeting, incontri, manifestazioni e novità su Perl.it.
Iscriviti!
D:
Annunci Google