Groovy :: 查找递归地映射

4

编辑 请参考@tim在下面提供的“正确”的Groovy式递归映射方法。由于Map findRecursive在Groovy中尚不存在,如果您发现自己需要在应用程序的各个部分中使用此功能,请将其添加到Map metaClass中:

Map.metaClass.findRecursive = {String key->
    if(delegate.containsKey(key)) return delegate."$key"
    else
        for(m in delegate) {
            if(m.value in Map) return m.value.findRecursive(key)
        }
}
// then anywhere in your app
someMap.findRecursive('foo')

翻译

本来以为类似findResult{it.key=='foo'}的方法可以递归查找多维映射元素,但似乎不是这样。
自己编写了递归映射查找器,但我想知道是否有更好的方法来完成这个任务。也许我错过了某些内置函数,或者有一种更优雅(简洁)的方式来实现以下功能:
Map map = [school:[id:'schoolID', table:'_school',
    children:[team:[id:'teamID',table:'_team',
        children:[player:[id:'playerID',table:'_roster']]
    ]]
]]

class Foo {
    static finder = {Map map, String key->
        if(map.containsKey(key)) return map[key]
        else
            for(m in map) {
                if(m.value in Map) return this.finder(m.value,key)
            }
    }
}
println Foo.finder(map,'team') 
1个回答

10

使用Groovy 1.8(findResult方法所需版本),你可以这样做:

class DeepFinder {
  static Object findDeep( Map map, Object key ) {
    map.get( key ) ?: map.findResult { k, v -> if( v in Map ) v.findDeep( key ) }
  }
}

use( DeepFinder ) {
  println map.findDeep( 'team' )
}

我不知道默认的Groovy方法中是否有递归方法...


+1 @tim,不错的替代方案。 (Map)m.findRecursive('foo')在Groovy.lang中将是一个不错的补充,我个人认为。 - virtualeyes
@virtual,我同意...也许可以为DGM提供一个补丁,编写几个测试,并将它们提交到JIRA?这样或许就能进入1.8.2版本了。 - tim_yates
可以先在Groovy用户组发布这个问题,也许这就是为什么还没有被实现的原因。同时,我编辑了我的帖子,添加了递归查找到Map元类(从可怕的LAMP堆栈中来,真的很惊人能够既拥有蛋糕又吃掉它;--)) - virtualeyes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接