2011-01-16 8 views
10

Tengo una clase de dominio que es solo una lista de cadenas (youtubeLinks).Actualizando "it" dentro de un cierre Groovy

Al guardar estos enlaces, quiero quitar la identificación del video y guardarla en lugar de la URL completa ingresada en el lado de la interfaz de usuario.

Esto es lo que estoy tratando (ignorar que la expresión regular es defectuoso)

youtubeLinks.each { 
def youtubeRegex = /v=(.*)/ 
def matcher = (it =~ youtubeRegex) 
it = matcher[0][1] 
} 

Cuando guardo esto, se guarda el valor original de "eso". ¿Hay alguna manera de actualizar esta referencia y guardarla correctamente?

Gracias.

Respuesta

21

El bucle each de Groovy es simplemente un iterador y, como tal, no afecta a la colección en la que opera, ni devuelve un valor propio. Es básicamente equivalente al "bucle for forzado (for-each)" de Java, solo con la conveniencia del tipado dinámico y una variable implícita de bucle (it). Si bien el it se puede modificar, es una empresa inútil, ya que simplemente cambiaría una referencia al valor original, no el valor en sí mismo. Consulte this question para obtener más información al respecto.

Cuando necesite modificar de algún modo todos los elementos de una colección, la solución idiomática de Groovy (Grails) es utilizar el método collect. Collect transforma cada elemento a través del cierre que usted proporciona, y finalmente devuelve una nueva colección (por lo tanto, en realidad no "modifica" nada).

Básicamente, es probable que desee hacer algo como esto:

def links = '''http://www.youtube.com/watch?v=fl6s1x9j4QQ 
http://www.youtube.com/watch?v=tCvMKcNJCAY 
''' 

assert (links =~ /watch\?v=(.*)/).collect{match -> match[1]} == ["fl6s1x9j4QQ", "tCvMKcNJCAY"] 

..Though en realidad hay varias maneras uno puede ir sobre una tarea de este tipo en Groovy.

Además, Ted Naleid's blog tiene algunos buenos ejemplos de la coincidencia de patrones de Groovy que pueden serle de utilidad.

Editar Aquí hay varias maneras en las que podría abreviar la solución que envió:

youtubeLinks = youtubeLinks.collect{link -> (link =~ /\?v=(.*)$/)[0][1]} 

o

youtubeLinks = youtubeLinks.collect{link -> link.replaceAll(/^.*\?v=/, "") } 

o este (Aunque es un poco artificiosa)

youtubeLinks = youtubeLinks.join('\n').replaceAll(/.*\?v=/, '').split() 
+0

Gracias! Voy a verificar esto. – user577905

+0

Me gustan sus ediciones. ¡Gracias! – user577905

+0

Respuesta genial. Pero el video en el segundo enlace ha sido eliminado = ( – epidemian

2

Usted fue ri ght, terminó siendo como

youtubeLinks = youtubeLinks.collect { 
    def youtubeRegex = /v=(.*)[&]/ 
    def matcher = (it =~ youtubeRegex) 
    return matcher[0][1] 
} 

Gracias, Northover.

+1

Me alegro de haber podido ayudar. He agregado algunas soluciones de trabajo adicionales a mi respuesta, si le interesan formas de consolidar el código. Saludos. – Northover

Cuestiones relacionadas