编写此代码的最佳方式,字符串在Groovy中映射转换

时间:2010-05-11 16:50:01

标签: string groovy map

我有一个像

这样的字符串
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])

   }

 }

它有效,但是有更有效的方法吗?

8 个答案:

答案 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]]
    }
}