Ответ 1
Цикл Groovy each
- это просто итератор, и поэтому он не влияет на коллекцию, на которой он работает, и не возвращает свое значение. Это в основном эквивалентно Java "advanced for loop (for-each)", только с удобством динамического ввода и неявной переменной цикла (it). Хотя it
можно изменить, это тщетное предприятие, так как вы просто будете менять ссылку на исходное значение, а не на само значение. Подробнее см. этот вопрос.
Когда вам нужно каким-либо образом изменить каждый элемент в коллекции, идиоматическим решением 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"]
.. Хотя на самом деле существует несколько способов решить такую задачу в Groovy.
Кроме того, блог Ted Naleid содержит несколько приятных примеров соответствия шаблонов Groovy, которые могут оказаться полезными.
Edit Вот несколько способов, с помощью которых вы могли бы сокращать решение, которое вы отправили:
youtubeLinks = youtubeLinks.collect{link -> (link =~ /\?v=(.*)$/)[0][1]}
или
youtubeLinks = youtubeLinks.collect{link -> link.replaceAll(/^.*\?v=/, "") }
или это (хотя это немного надуманно)
youtubeLinks = youtubeLinks.join('\n').replaceAll(/.*\?v=/, '').split()