Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Groovy: isn't there a stringToMap out of the box?

as a tcl developer starting with groovy, I am a little bit surprised about the list and map support in groovy. Maybe I am missing something here.

I am used to convert between strings, lists and arrays/maps in tcl on the fly. In tcl, something like

"['a':2,'b':4]".each {key, value -> println key + " " + value} 

would be possible, where as in groovy, the each command steps through each character of the string.

This would be much of a problem is I could easily use something like the split or tokenize command, but because a serialized list or map isn't just "a:2,b:4", it is a little bit harder to parse.

It seems that griffon developers use a stringToMap library (http://code.google.com/p/stringtomap/) but the example can't cope with the serialized maps either.

So my question is now: what's the best way to parse a map or a list in groovy?

Cheers, Ralf

PS: it's a groovy question, but I've tagged it with grails, because I need this functionality for grails where I would like to pass maps through the URL

Update: This is still an open question for me... so here are some updates for those who have the same problem:

  • when you turn a Map into a String, a .toString() will result in something which can't be turned back into a map in all cases, but an .inspect() will give you a String which can be evaluated back to a map!
  • in Grails, there is a .encodeAsJSON() and JSON.parse(String) - both work great, but I haven't checked out yet what the parser will do with JSON functions (possible security problem)
like image 279
rdmueller Avatar asked Feb 06 '10 09:02

rdmueller


2 Answers

You might want to try a few of your scenarios using evaluate, it might do what you are looking for.

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" 
like image 112
John Wagenleitner Avatar answered Sep 22 '22 04:09

John Wagenleitner


Not exactly native groovy, but useful for serializing to 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) 

with meta-programming:

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 

unfortunately, it's not possible to override the toString() method...

like image 26
Jonas Eicher Avatar answered Sep 19 '22 04:09

Jonas Eicher