Domanda

come sviluppatore TCL inizia con groove, io sono un po 'sorpreso per il sostegno e la lista mappa in Groovy. Forse mi manca qualcosa qui.

Sono abituato per la conversione tra stringhe, liste e array / mappe in tcl al volo. In tcl, qualcosa come

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

sarebbe possibile, dove come in scanalato, le fasi di comando ciascuno attraverso ogni carattere della stringa.

Questo sarebbe un gran problema è ho potuto facilmente usare qualcosa come la scissione o il comando tokenize, ma perché una lista o una mappa serializzato non è solo "un: 2, B: 4", è un po 'più difficile per analizzare.

Sembra che gli sviluppatori di grifoni utilizzare una libreria stringToMap ( http://code.google.com/p / stringtomap / ), ma l'esempio non può far fronte con le mappe serializzati sia.

Quindi la mia domanda è ora: qual è il modo migliore per analizzare una mappa o un elenco in Groovy

Saluti, Ralf

PS: è una questione Groovy, ma ho etichettato con Grails, perché ho bisogno di questa funzionalità per graal in cui mi piacerebbe passare le mappe tramite l'URL

Aggiornamento: Questa è ancora una questione aperta per me ... quindi ecco alcuni aggiornamenti per coloro che hanno lo stesso problema:

  • quando si accende una mappa in una stringa, un .toString() si tradurrà in qualcosa che non può essere trasformato di nuovo in una mappa in tutti i casi, ma un .inspect() vi darà una stringa che può essere valutato di nuovo a una mappa!
  • in Grails, c'è un .encodeAsJSON() e JSON.parse(String) - entrambi funzionano molto bene, ma non ho verificato ancora che cosa il parser che fare con le funzioni di JSON (possibile problema di sicurezza)
È stato utile?

Soluzione

Non esattamente nativo Groovy, ma utile per la serializzazione a 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)

con meta-programmazione:

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

purtroppo, non è possibile eseguire l'override del metodo toString () ...

Altri suggerimenti

Si potrebbe desiderare di provare alcuni dei vostri scenari utilizzando valutare , si potrebbe fare quello che stai cercando.

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"

Credo che siete alla ricerca di una combinazione di ConfigObject ConfigSlurper. Qualcosa di simile a questo sarebbe fare il trucco.

def foo = new ConfigObject()
foo.bar = [ 'a' : 2, 'b' : 4 ]

// we need to serialize it
new File( 'serialized.groovy' ).withWriter{ writer ->
  foo.writeTo( writer )
}

def config = new ConfigSlurper().parse(new File('serialized.groovy').toURL())    

// highest level structure is a map ["bar":...], that's why we need one loop more
config.each { _,v ->
    v.each {key, value -> println key + " " + value}
}

Se non si desidera utilizzare la valutazione (), fare, invece:

def stringMap = "['a':2,'b':4]"
stringMap = stringMap.replaceAll('\\[|\\]','')
def newMap = [:]
stringMap.tokenize(',').each {
kvTuple = it.tokenize(':')
newMap[kvTuple[0]] = kvTuple[1]
}
println newMap
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top