2011-01-16 14 views
10

Mam klasy domeny, która jest tylko lista ciągi (youtubeLinks).Aktualizowanie "go" wewnątrz zamknięcia Groovy

Podczas zapisywania tych linków chcę usunąć identyfikator wideo i zapisać go zamiast całego adresu URL wprowadzonego po stronie interfejsu użytkownika.

To co usiłuję (ignorować że regex jest błędna)

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

Kiedy zapisać to, że oszczędza oryginalną wartość „to”. Czy istnieje sposób aktualizacji tego odniesienia i czy jest on poprawnie zapisywany?

Dzięki.

Odpowiedz

21

Pętla Groovy's each jest tylko iteratorem i jako taka nie wpływa na kolekcję, na której działa, ani nie zwraca wartości własnej. Zasadniczo jest to odpowiednik "zaawansowanej pętli for for Java" (dla każdego), tylko z wygodą dynamicznego pisania i niejawnej zmiennej pętli (it). Chociaż można zmodyfikować it, to jest to daremne przedsięwzięcie, ponieważ po prostu zmieniasz odniesienie do pierwotnej wartości, a nie samą wartość. Więcej informacji na ten temat można znaleźć na stronie this question.

Kiedy trzeba zmodyfikować każdy element w kolekcji, idiomatyczne rozwiązanie Groovy (Grails) ma korzystać z metody collect. Collect dokonuje transformacji każdego elementu poprzez zamknięcie, które zapewniasz, ostatecznie zwracając nową kolekcję (tak, że tak naprawdę "nie modyfikuje" niczego).

Zasadniczo, prawdopodobnie będziesz chciał zrobić coś takiego:

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 nie są w rzeczywistości wiele sposobów można go o takiego zadania w Groovy.

Dodatkowo, Ted Naleid's blog ma kilka ładnych przykładów dopasowywania wzorców Groovy, które mogą okazać się przydatne.

Edit Oto kilka sposobów, które można skracać rozwiązania, których przedstawiać:

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

lub

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

czy to (choć trochę wymyślony)

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

Dzięki! Sprawdzę to. – user577905

+0

Podoba mi się twoje zmiany. Dzięki! – user577905

+0

Fajna odpowiedź. Ale film z drugiego linku został usunięty = ( – epidemian

2

Byłeś ri W końcu okazało się, że jest to podobne do:

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

Dzięki, Northover.

+1

Cieszę się, że mogłem pomóc. Dodałem kilka dodatkowych rozwiązań roboczych do mojej odpowiedzi, jeśli interesuje Cię sposób konsolidacji kodu. – Northover

Powiązane problemy