Grails 更新「;它";在Groovy闭包中

Grails 更新「;它";在Groovy闭包中,grails,groovy,closures,Grails,Groovy,Closures,我有一个域类,它只是一个字符串列表(youtubeLinks) 保存这些链接时,我想去掉视频ID并保存它,而不是保存在UI端输入的整个URL 这就是我正在尝试的(忽略正则表达式有缺陷) 当我保存这个时,它保存了“it”的原始值。是否有方法更新此引用并将其正确保存 谢谢 Groovy的每个循环仅仅是一个迭代器,因此它既不影响它所操作的集合,也不返回它自己的值。它基本上等同于Java的“advanced for loop(for each)”,只是方便了动态类型和隐式循环变量(It)。虽然it可以修

我有一个域类,它只是一个字符串列表(youtubeLinks)

保存这些链接时,我想去掉视频ID并保存它,而不是保存在UI端输入的整个URL

这就是我正在尝试的(忽略正则表达式有缺陷)

当我保存这个时,它保存了“it”的原始值。是否有方法更新此引用并将其正确保存


谢谢

Groovy的
每个
循环仅仅是一个迭代器,因此它既不影响它所操作的集合,也不返回它自己的值。它基本上等同于Java的“advanced for loop(for each)”,只是方便了动态类型和隐式循环变量(It)。虽然
it
可以修改,但这是徒劳的,因为您只需更改对原始值的引用,而不是值本身。更多信息请参见

当您需要以某种方式修改集合中的每个元素时,惯用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"]
…尽管实际上在Groovy中有很多方法可以完成这样的任务

此外,还有一些很好的Groovy模式匹配示例,您可能会发现这些示例很有用

编辑 以下是您可以缩写提交的解决方案的几种方法:

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

或者这个(尽管有点做作)


你是对的,结果是

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

谢谢,诺瑟弗。

谢谢!我来看看。回答很酷。但是第二个链接上的视频已被删除=(很高兴我能提供帮助。如果您对整合代码的方法感兴趣,我已经在我的答案中添加了一些额外的工作解决方案。干杯。
youtubeLinks = youtubeLinks.collect{link -> link.replaceAll(/^.*\?v=/, "") }
youtubeLinks = youtubeLinks.join('\n').replaceAll(/.*\?v=/, '').split()
youtubeLinks = youtubeLinks.collect {
    def youtubeRegex = /v=(.*)[&]/
    def matcher = ( it =~ youtubeRegex )
    return matcher[0][1]
}