我有一个像
这样的字符串def data = "session=234567893egshdjchasd&userId=12345673456&timeOut=1800000"
我想将其转换为地图
["session", 234567893egshdjchasd]
["userId", 12345673456]
["timeout", 1800000]
这是我现在这样做的方式,
def map = [:]
data.splitEachLine("&"){
it.each{ x ->
def object = x.split("=")
map.put(object[0], object[1])
}
}
它有效,但是有更有效的方法吗?
答案 0 :(得分:23)
我不知道认为这会更快地运行,但它的确表现在语法简约性方面:
def data = 'session=234567893egshdjchasd&userId=12345673456&timeOut=1800000'
def result = data.split('&').inject([:]) { map, token ->
token.split('=').with { map[it[0]] = it[1] }
map
}
就个人而言,我喜欢Don在可读性和可维护性方面的答案,但根据具体情况,这可能是合适的。
编辑:这实际上是一个重新格式化的单行。
答案 1 :(得分:13)
我不知道这是否更有效,但在我看来,它更简单(YMMV)
def data = "session=234567893egshdjchasd&userId=12345673456&timeOut=1800000"
def map = [:]
data.split("&").each {param ->
def nameAndValue = param.split("=")
map[nameAndValue[0]] = nameAndValue[1]
}
答案 2 :(得分:6)
如果您正在寻找有效的正则表达式,请访问:
def data = "session=234567893egshdjchasd&userId=12345673456&timeOut=1800000"
def map = [:]
data.findAll(/([^&=]+)=([^&]+)/) { full, name, value -> map[name] = value }
println map
打印:
[session:234567893egshdjchasd, userId:12345673456, timeOut:1800000]
如果你不熟悉正则表达式,它可能看起来有点异国情调,但实际上并不复杂。它只有两个(组),第一组是任何字符,但是“&”或者是“=”。第二组是除“=”之外的任何字符。捕获组位于“=”的两侧。
答案 3 :(得分:2)
经过一些搜索,“collectEntries()”是一个神奇的东西,它会创建一个地图元素。像“collect()”一样工作,创建一个列表。所以给出了
def params = "a1=b1&a2=b2&a3&a4=&a5=x=y"
单线是
map = params.tokenize("&").collectEntries{
it.split("=",2).with{
[ (it[0]): (it.size()<2) ? null : it[1] ?: null ]
}
}
创建
map = [a1:b1, a2:b2, a3:null, a4:null, a5:x=y]
根据您要处理案例“a3”和“a4 =”的方式,您也可以使用稍短的版本
...
[ (it[0]): (it.size()<2) ? null : it[1] ]
...
然后你明白了:
map = [a1:b1, a2:b2, a3:null, a4:, a5:x=y]
答案 4 :(得分:1)
如果您使用的是grails控制器,那么这很简单:
GrailsParameterMap map = new GrailsParameterMap(request)
http://grails.org/doc/latest/api/org/codehaus/groovy/grails/web/servlet/mvc/GrailsParameterMap.html
答案 5 :(得分:1)
如果您使用Grails,我找到的最好的方法是WebUtils函数fromQueryString。
https://grails.github.io/grails-doc/2.0.x/api/org/codehaus/groovy/grails/web/util/WebUtils.html
答案 6 :(得分:1)
这是我的努力,它一次性初始化并填充地图,并避免我个人难以遵循的注入方法: -
def map = data.split('&').collectEntries {
def kvp = it.split('=').collect { string ->
string = string.trim()
return string
}
[(kvp[0]): kvp.size() > 1 ? kvp[1] ?: '' : '']
// the null check is almost certainly overkill so you could use :-
// [(kvp[0]): kvp.size() > 1 ? kvp[1] : '']
// this just checks that a value was found and inserts an empty string instead of null
}
答案 7 :(得分:0)
我完全不建议使用split。
Split将创建一个新字符串,而在创建环境变量集合时,您可能需要一个列表列表。
在初始中断(&)和嵌套中断(=)上都进行标记。尽管大多数解释程序仍然可以使用,但有些解释程序可能会按字面意义运行拆分,最终您将得到一个字符串列表,而不是地图列表。
def data= "test1=val1&test2=val2"
def map = [:]
map = data.tokenize("&").collectEntries {
it.tokenize("=").with {
[(it[0]):it[1]]
}
}