Best way to code this, string to map conversion in Groovy

I don't know think this is would run any faster, but it does suggest itself in terms of syntactic parsimony:

def data = 'session=234567893egshdjchasd&userId=12345673456&timeOut=1800000'
def result = data.split('&').inject([:]) { map, token -> 
    //Split at "=" and return map with trimmed values
    token.split('=').with { 
        map[it[0].trim()] = it[1].trim() 
    }
    map 
}

Personally, I like Don's answer for readability and maintainability, but depending on context, this may be appropriate.

Edit: This is actually a reformatted one-liner.


After some searching, "collectEntries()" is the magic thing to use, it creates a map element. Work just like "collect()" that creates a list. So given

def params = "a1=b1&a2=b2&a3&a4=&a5=x=y"

the one-liner is

map = params.tokenize("&").collectEntries{ 
          it.split("=",2).with{ 
              [ (it[0]): (it.size()<2) ? null : it[1] ?: null ] 
          }
      }

which creates

map = [a1:b1, a2:b2, a3:null, a4:null, a5:x=y]

Depending how you want to handle the cases "a3" and "a4=" you can also use a slightly shorter version

...
[ (it[0]): (it.size()<2) ? null : it[1] ] 
...

and then you get this:

map = [a1:b1, a2:b2, a3:null, a4:, a5:x=y]

I don't know if this is more efficient, but to my eyes, it's a bit simpler (YMMV)

def data = "session=234567893egshdjchasd&userId=12345673456&timeOut=1800000"
def map = [:]

data.split("&").each {param ->
    def nameAndValue = param.split("=")
    map[nameAndValue[0]] = nameAndValue[1]
}

If you're looking for efficient, regular expressions are where it's at:

def data = "session=234567893egshdjchasd&userId=12345673456&timeOut=1800000"
def map = [:]
data.findAll(/([^&=]+)=([^&]+)/) { full, name, value ->  map[name] = value }

println map

prints:

[session:234567893egshdjchasd, userId:12345673456, timeOut:1800000]

If you're not familiar with regular expressions, it might look a little foreign, but it's really not that complicate. It just has two (groups), the first group is any character but a "&" or a "=". The second group is any character besides a "=". The capture groups are on either side of a "=".

Tags:

String

Groovy

Map