Groovy:是不是有开箱即用的stringToMap?

rdm*_*ler 24 string grails groovy map params

作为一个以groovy开头的tcl开发人员,我对groovy中的列表和地图支持感到有些惊讶.也许我在这里遗漏了一些东西.

我习惯在tcl中即时转换字符串,列表和数组/映射.在tcl中,类似于

"['a':2,'b':4]".each {key, value -> println key + " " + value}
Run Code Online (Sandbox Code Playgroud)

是可能的,在groovy中,每个命令都会遍历字符串的每个字符.

这可能是一个很大的问题,因为我可以轻松地使用像split或tokenize命令这样的东西,但由于序列化的列表或映射不仅仅是"a:2,b:4",因此解析起来有点困难.

似乎griffon开发人员使用stringToMap库(http://code.google.com/p/stringtomap/),但该示例也无法处理序列化地图.

所以现在我的问题是:在groovy中解析地图或列表的最佳方法是什么?

干杯,拉尔夫

PS:这是一个时髦的问题,但我用grails标记了它,因为我需要grails的这个功能,我想通过URL传递地图

更新:对我来说,这仍然是一个悬而未决的问题......所以这里有一些针对同样问题的人的更新:

  • 当你把一个Map变成一个String时,a .toString()会导致在所有情况下都无法转换回地图的东西,但是.inspect()会给你一个可以回溯到地图的String!
  • 在Grails中,有一个- .encodeAsJSON()并且JSON.parse(String)- 两者都很棒,但我还没有检查解析器将使用JSON函数做什么(可能的安全问题)

Joh*_*ner 24

您可能希望使用evaluate尝试一些场景,它可能会执行您要查找的内容.

def stringMap = "['a':2,'b':4]"
def map = evaluate(stringMap)

assert map.a == 2
assert map.b == 4

def stringMapNested = "['foo':'bar', baz:['alpha':'beta']]"
def map2 = evaluate(stringMapNested)

assert map2.foo == "bar"
assert map2.baz.alpha == "beta"
Run Code Online (Sandbox Code Playgroud)

  • 您可以在GroovyShell上使用`Eval`类,它是一个简单的帮助器:`def map = Eval.me("['a':2,'b':4]") (3认同)

Jon*_*her 13

不完全是原生的groovy,但对于序列化为JSON很有用:

import groovy.json.JsonBuilder
import groovy.json.JsonSlurper

def map = ['a':2,'b':4 ]
def s = new JsonBuilder(map).toString()
println s

assert map == new JsonSlurper().parseText(s)
Run Code Online (Sandbox Code Playgroud)

使用元编程:

import groovy.json.JsonBuilder
import groovy.json.JsonSlurper

Map.metaClass.toJson   = { new JsonBuilder(delegate).toString() }
String.metaClass.toMap = { new JsonSlurper().parseText(delegate) }

def map = ['a':2,'b':4 ]
assert map.toJson() == '{"a":2,"b":4}'
assert map.toJson().toMap() == map
Run Code Online (Sandbox Code Playgroud)

不幸的是,它无法覆盖toString()方法......