代码之家  ›  专栏  ›  技术社区  ›  rdmueller

groovy:难道没有一个字符串tomap是现成的吗?

  •  22
  • rdmueller  · 技术社区  · 16 年前

    作为一个从groovy开始的TCL开发人员,我对groovy中的列表和映射支持有点惊讶。也许我错过了什么。

    我习惯于在TCL中动态转换字符串、列表和数组/映射。在TCL,有点像

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

    这是可能的,就像在groovy中一样,每个命令都会逐步通过字符串的每个字符。

    这是一个很大的问题,我可以很容易地使用split或tokenize命令,但是因为序列化列表或映射不仅仅是“a:2,b:4”,所以解析起来有点困难。

    Griffon开发人员似乎使用了一个StringTomap库( http://code.google.com/p/stringtomap/ )但是这个示例也不能处理序列化的映射。

    所以我现在的问题是:在groovy中解析映射或列表的最佳方法是什么?

    干杯, 拉尔夫

    PS:这是一个绝妙的问题,但我已经用grails标记了它,因为我需要grails的这个功能,在那里我想通过URL传递映射

    更新: 这对我来说仍然是个悬而未决的问题…因此,以下是对那些有相同问题的人的一些更新:

    • 当你把地图变成一个字符串时, .toString() 在任何情况下都会导致无法恢复为地图的内容,但 .inspect() 会给你一个字符串,它可以被计算回一个映射!
    • 在圣杯里,有一个 .encodeAsJSON() JSON.parse(String) -两者都很好,但是我还没有检查解析器将如何处理JSON函数(可能的安全问题)。
    4 回复  |  直到 11 年前
        1
  •  11
  •   rdmueller    11 年前

    不完全是本地的groovy,但对于序列化到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)
    

    使用元编程:

    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
    

    不幸的是,无法重写toString()方法…

        2
  •  22
  •   John Wagenleitner    16 年前

    您可能想尝试使用 评价 可能会满足你的需求。

    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"
    
        3
  •  3
  •   Grega KeÅ¡pret    16 年前

    我想你要找的是 ConfigObject 和configslurper。像这样的东西就可以了。

    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}
    }
    
        4
  •  1
  •   Noam Manos    12 年前

    如果不想使用evaluate(),请改为:

    def stringMap = "['a':2,'b':4]"
    stringMap = stringMap.replaceAll('\\[|\\]','')
    def newMap = [:]
    stringMap.tokenize(',').each {
    kvTuple = it.tokenize(':')
    newMap[kvTuple[0]] = kvTuple[1]
    }
    println newMap