grails - 在 Groovy 闭包内更新 "it"

标签 grails groovy closures

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

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

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

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

当我保存它时,它会保存“它”的原始值。有没有办法更新这个引用并正确保存它?

谢谢。

最佳答案

Groovy 的 each loop 只是一个迭代器,因此它既不影响它操作的集合,也不返回它自己的值。它基本上等同于 Java 的“高级 for 循环(for-each)”,只是具有动态类型和隐式循环变量(it)的便利性。虽然 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"]

..虽然实际上有很多方法可以在 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()

关于grails - 在 Groovy 闭包内更新 "it",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4708838/

相关文章:

grails - 将其他文件添加到 Grails WAR 文件

grails - Grails,未调用 Controller ,但 View 已更新

javascript - 关于这个和 javascript 中的 self

r - 在R中的闭包中访问变量

postgresql - 生成重复的唯一约束名称

grails - 从hudson运行 'run-app'命令

json - Grails呈现JSON

grails - 带有获取参数的列表

java - 使用 querydsl-maven-plugin 和 groovy-eclipse-compiler 生成 QueryDsl 类

javascript - ajax回调函数可以看到父函数的变量吗?