2011-01-16 4 views
10

도메인 클래스는 문자열 목록 (youtubeLinks)입니다.Groovy 클로저의 "it"업데이트

이러한 링크를 저장할 때 동영상 ID를 제거하고 UI 측에 입력 한 전체 URL 대신 저장하고 싶습니다.

이 내가이를 저장하면

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

, 그것은 "을"의 원래 값을 저장 (정규식 결함이 있음을 무시하는) 노력하고있어입니다. 이 참조를 업데이트하고 올바르게 저장하는 방법이 있습니까?

감사합니다.

답변

21

Groovy의 each 루프는 단지 반복자이므로 루프가 작동하는 콜렉션에는 영향을 미치지 않으며 자체의 값도 반환하지 않습니다. 기본적으로 Java의 "고급 for 루프 (for-each)"와 동등합니다. 동적 타이핑과 암시 적 루프 변수의 편리함 만 있습니다. it은 수정할 수 있지만 값 자체가 아닌 원래 값에 대한 참조 만 변경하기 때문에 쓸모없는 기업입니다. 그것에 대한 자세한 내용은 this question을 참조하십시오.

어떤 식 으로든 콜렉션 내의 모든 요소를 ​​수정해야하는 경우, 관용적 인 Groovy (Grails) 솔루션은 collect 메소드를 사용합니다. 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.

또한 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, 그것은 결국 같았 어.

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

고마워, 노스 오버.

+1

다행히 도울 수 있습니다. 코드 통합 방법에 관심이 있다면 제 대답에 몇 가지 추가 솔루션을 추가했습니다. – Northover