2011-01-16 2 views
10

У меня есть класс домена, который является всего лишь списком строк (youtubeLinks).Обновление «it» внутри закрытия Groovy

При сохранении этих ссылок я хочу снять идентификатор видео и сохранить его вместо всего URL-адреса, введенного на стороне пользовательского интерфейса.

Это то, что я пытаюсь (игнорировать, что регулярное выражение является ошибочным)

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

Когда я сохраняю это, она сохраняет исходное значение «оно». Есть ли способ обновить эту ссылку и сохранить ее правильно?

Спасибо.

ответ

21

цикл Groovy's each - это просто итератор, и поэтому он не влияет на коллекцию, на которой он работает, и не возвращает свое значение. Это в основном эквивалентно «расширенному циклу for» (для каждого), «только с удобством динамического ввода и неявной переменной цикла (it). В то время как it может быть изменен, это бесполезное предприятие, так как вы просто будете менять ссылку на исходное значение, а не на само значение. Подробнее см. В разделе this question.

Если вам нужно каким-либо образом модифицировать каждый элемент внутри коллекции, то идиоматическое решение Groovy (Grails) должно использовать метод collect. Сбор преобразует каждый элемент через закрытие, которое вы предоставляете, в конечном итоге возвращающее новую коллекцию (так что она фактически не «ничего» не модифицирует).

В принципе, вы, вероятно, хотите сделать что-то вроде этого:

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 есть на самом деле несколько способов можно идти о такой задачи в Groovy.

Кроме того, Ted Naleid's blog содержит несколько хороших примеров сопоставления шаблонов Groovy, которые могут вам пригодиться.

Редактировать Вот несколько способов, которыми вы могли бы сокращаем решение Вы представили:

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

или

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

или это (хотя это немного надуманный)

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

Спасибо! Я проверю это. – user577905

+0

Мне нравятся ваши правки. Благодаря! – user577905

+0

Прохладный ответ. Но видео по второй ссылке было удалено = ( – epidemian

2

Вы были ri ght, это оказалось как

Спасибо, Northover.

+1

Рад, что я могу помочь. Я добавил некоторые дополнительные рабочие решения для своего ответа, если вас интересуют способы консолидации кода. Cheers. – Northover

Смежные вопросы