2010-08-26 13 views
13

En Perl, ¿es posible finalizar arbitrariamente una ejecución de map, p. algo equivalente a last en un bucle?¿Hay algo así como `last` for` map`?

Sería un poco como esto:

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

Consulte [¿Es "el mapa" un bucle?] (Http://stackoverflow.com/questions/3019925/is-map-a-loop) para obtener una pregunta relacionada. – Zaid

Respuesta

19

Nop. No puede last, next, etc. de un map, grep o sort bloques porque they are not loops.

Habiendo dicho eso, el fragmento de código en la pregunta es una práctica deficiente porque map nunca se debe llamar en contexto vacío. Se supone que deben usarse para transformar una lista en otra.

Aquí hay una mejor manera de escribirlo si realmente debe inline que (modificado según el comentario de ysth):

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

gracias por su respuesta. Sobre la cosa de "parctice pobre", bueno ... el código "dosomething" está destinado a ... hacer algo – benzebuth

+6

@benzebuth: No estaba hablando del 'do_something'. Deberías estar realmente usando 'map' para devolver una lista. – Zaid

+0

gracias. Ahora lo entiendo. Muy útil de hecho. +1 – benzebuth

3

No. Use un ordinal foreach bucle y la declaración last.

Desde 5.8.1, map is context aware - en el contexto vacío, no se construye ninguna lista. De todos modos, el mapa se usa generalmente para obtener una lista de otra lista, evaluando expr para cada elemento de la lista original.

2

Puede utilizar un salto de longitud (eval/die par) para rescatar a las de cualquier construcción anidada que no soporta directamente:

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

Pero como Zaid dijo, usando un bucle for/foreach en este caso es mejor porque no está utilizando el valor de retorno de map.

+0

map no construye una lista en contexto vacío: http://perldoc.perl.org/perlfaq6.html#What%27s-wrong-with-using-grep-in-a-void-context? –

+0

@eugene => eso es cierto, pero es un poco engañoso usar 'map' sin el valor de retorno. si desea la posición invertida de acción y valores, es mejor usar 'dosomething for ... ' –

+0

, con la excepción cuando, por algún motivo, desea proporcionar un contexto de lista dosificadora (pero en realidad no desea la lista devuelta) - a caso raro. para proporciona contexto vacío a dosificar (y grep proporcionaría contexto escalar) – ysth

2

¿Quieres un bucle for:

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

Se hace lo mismo. map es para transformar una lista en otras listas.

3

Se puede usar un do-bloque con un modificador de declaración:

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

Aunque el uso de un bloque foreach probablemente sería más claro, y futuros encargados del mantenimiento de su código se lo agradecerán.

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

Existen construcciones tipo mapa que hacen exactamente lo que usted desea hacer. Echar un vistazo a List::Util y List::MoreUtils (también convenientemente empaquetados juntos como List::AllUtils):

use List::MoreUtils 'first'; 

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

Si no desea extraer un elemento (s) de la lista, a continuación, utilizar foreach, de acuerdo con las respuestas anteriores.

-1

Prueba goto LABEL. Sin embargo, no sé qué tan seguro es eso.

+0

Alguien marcó esto como no una respuesta, pero esto se ve bien para mí. Probablemente no sea la mejor respuesta, dado que no tiene suficientes votos y otras respuestas tienen toneladas, pero eso no garantiza que no se trate de una respuesta. – ArtOfWarfare

+1

Es una respuesta de muy baja calidad en una ** publicación de 4 años ** que tiene muchas otras respuestas mejores ... no agrega nada a esta pregunta y en mi humilde opinión debe ser downvoted y eventualmente eliminado. – Frazz

+0

Puede ser de "baja calidad", pero no es VLQ. Solo downvote y déjalo. – JasonMArcher

Cuestiones relacionadas