2010-08-26 8 views
13

In Perl, è possibile terminare arbitrariamente un'esecuzione map, ad es. qualcosa di equivalente a last in un ciclo?C'è qualcosa come "last` per` map`?

Sarebbe un po 'come questo:

map { 
    if (test == true) { last; } dosomething 
} @myarray 
+4

Vedere [È "mappa" un ciclo?] (Http://stackoverflow.com/questions/3019925/is-map-a-loop) per una domanda correlata. – Zaid

risposta

19

Nope. Non è possibile , next, ecc. Di un map, grep o sort blocchi perché they are not loops.

Detto questo, il frammento di codice nella domanda è una cattiva pratica perché map non dovrebbe mai essere chiamato nel contesto vuoto. Dovrebbero essere usati per trasformare una lista in un'altra.

Ecco un modo migliore per scriverlo se proprio deve inline esso (modificato dopo il commento di ysth):

$_ == 10 && last, print for 1..15; # prints '123456789' 
+0

grazie per la risposta. Riguardo alla cosa "povero parctice", beh ... il pezzo di codice "dosomething" è destinato a ... fare qualcosa – benzebuth

+6

@benzebuth: Non stavo parlando del 'do_something'. Dovresti usare davvero 'map' per restituire una lista. – Zaid

+0

grazie. Ora capisco. Davvero molto utile. +1 – benzebuth

3

N. Uso un numero ordinale foreach loop e la dichiarazione last.

Dal 5.8.1, map is context aware - nel contesto vuoto, non vengono creati elenchi. In ogni caso, la mappa viene generalmente utilizzata per ottenere una lista da un'altra lista, valutando expr per ogni elemento della lista originale.

2

È possibile utilizzare un salto in lungo (eval/die coppia) per salvare qualsiasi costrutto nidificato che non supporta direttamente esso:

eval { map{ die if test; dosomething } @myarray }; 

Ma, come detto Zaid, utilizzando un ciclo for/foreach in questo caso è migliore perché non stai utilizzando il valore restituito di map.

+0

map non crea un elenco nel contesto vuoto: http://perldoc.perl.org/perlfaq6.html#What%27s-wrong-with-using-grep-in-a-void-context? –

+0

@eugene => questo è vero, ma è un po 'fuorviante usare 'map' senza il valore restituito. se si desidera la posizione invertita di azione e valori, è meglio usare 'dosomething per ... ' –

+0

l'eccezione è quando per qualche motivo si desidera fornire un contesto lista dosomething (ma in realtà non si desidera l'elenco restituito) - un caso raro. per fornire un contesto vuoto a dosomething (e grep fornirebbe un contesto scalare) – ysth

2

Volete un ciclo for:

foreach (@myarray) { 
    last if test; 
    ... 
} 

Si fa la stessa cosa. map serve per trasformare una lista in altre liste.

3

Si potrebbe usare un fai-blocco con un modificatore per la dichiarazione:

do { 
    last if test; 
    dosomething; 
} for (@myarray); 

Pur utilizzando un blocco foreach sarebbe probabilmente più chiara, e future manutentori del codice vi ringrazieranno.

foreach (@myarray) { 
    last if test; 
    dosomething; 
} 
1

Ci sono costrutti simili a mappe che fanno esattamente ciò che si vuole fare. Date un'occhiata a List::Util e List::MoreUtils (comodamente anche confezionato insieme come List::AllUtils):

use List::MoreUtils 'first'; 

# get first element with a {foo} key 
my $match = map { $_->{foo} eq 'some string' } @elements; 

Se non si desidera estrarre un elemento (s) dall'elenco, quindi utilizzare foreach, come per le risposte precedenti.

-1

Prova goto ETICHETTA. Tuttavia non so quanto sia sicuro.

+0

Qualcuno ha contrassegnato questo come non essendo una risposta, ma questo mi sembra a posto. Probabilmente non è la risposta migliore, dato che non ha voti positivi e altre risposte hanno tonnellate, ma questo non giustifica il fatto di non avere una risposta. – ArtOfWarfare

+1

È una risposta di qualità molto bassa su un ** post di 4 anni ** che ha molte altre risposte migliori ... non aggiunge nulla a questa domanda e dovrebbe IMHO essere downvoted ed eventualmente eliminato. – Frazz

+0

Potrebbe essere "bassa qualità", ma non è VLQ. Solo downvote e lascia. – JasonMArcher