2011-04-07 7 views
14

He estado escribiendo código perl a tiempo completo durante un par de meses (bioinformática), y siempre estoy tratando de mejorar mis habilidades. Solo hoy, caí en la cuenta de que nunca uso map o grep. Mirando hacia atrás a través de mi código, me doy cuenta de que estas herramientas podrían ahorrarme un par de líneas aquí o allá, pero solo a expensas de la flexibilidad de un ciclo foreach. Mi pregunta es la siguiente:El uso de map o grep en Perl

¿Hay alguna circunstancia que haya encontrado donde usar map o grep haya traído una ventaja significativa sobre un bucle foreach/for, más allá de guardar una línea o dos de código?

¡Gracias por su tiempo!

+1

Un mapa puede estar en línea con una expresión más grande. Un foreach no puede. –

Respuesta

40

El Schwartzian Transform sería un ejemplo:

@sorted = map { $_->[0] } 
      sort { $a->[1] cmp $b->[1] } 
      map { [$_, foo($_)] } 
      @unsorted; 

se puede hacer eso con una pila de foreach bucles, sino que tendría que recogerlos, aparte de averiguar lo que estaba pasando; una vez que has visto la Transformación Schwartzian, reconoces el modismo inmediatamente.

En general, creo que map y grep son buenos porque le permiten representar clara y compactamente su intención sin capas de sintaxis. Si ve un map, entonces sabrá que está ocurriendo algún tipo de transformación simple de la estructura de datos; Si ve un grep, entonces sabrá que se está realizando algún tipo de filtrado/selección. Puede hacerlo todo con foreach pero la intención de su código no es tan clara como con map o grep; incluso podría hacerlo todo con if y goto si así lo deseara, pero luego su intento quedaría oculto bajo aún más sintaxis y seguimiento del estado.

+0

gracias por responder mi pregunta de forma concisa. Definitivamente usaré Schwartzian Transfers en el futuro, y he tenido que hackear ese tipo de problemas hasta ahora. – wespiserA

+5

@wespiserA: Y preste atención a Tanktalus en 'List :: MoreUtils', ese paquete ofrece algunas buenas herramientas para hacer que su código coincida con sus intenciones. –

+4

+1 para el segundo párrafo. Perl tiene muchos comandos que son técnicamente intercambiables, así que elige aquel cuya semántica transmita más claramente tu intención a los humanos que leerán tu código en el futuro. –

16

Estoy constantemente usando map y grep. Y apply, first, any y muchos otros de List::MoreUtils. Me parece que, en general, explican lo que está haciendo el código en comparación con cómo el código lo está haciendo.

En general, me parece que cuando mi código se lee igual que la especificación, es más probable que sea correcto y que sea más probable que maneje casos de esquina/borde. Perl me permite hacer esto mucho mejor que cualquier otro idioma que haya usado en el pasado, y lo aprovecho.

Por ejemplo, si mi especificación dice que voy a hacer si foo()$blah está en alguna lista, mi código lee exactamente de esa manera:

foo() if any { $_ eq $blah } some_list(); 

La misma idea para el resto de estas herramientas. El código y la especificación son extrañamente similares, y esa es una de las mejores cosas de Perl.

+0

Lista :: MoreUtils tiene muchos subidas geniales. Gracias. – wespiserA

+0

El concepto detrás de lo que explica en esta respuesta (especialmente el comentario "qué está haciendo el código en lugar de cómo lo está haciendo el código"): http://en.wikipedia.org/wiki/Functional_programming – tokland

Cuestiones relacionadas