2011-05-31 123 views
4

编辑 请参阅下面的@ tim解决方案,了解“正确”的Groovy-esque方法来映射递归。由于地图findRecursive还不在Groovy存在,如果你发现自己需要在你的应用程序的不同部分这种功能,只是将其添加到地图的metaClass:Groovy ::地图查找递归

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 {它。 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') 

回答

10

使用Groovy 1.8(REQD为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的方法,我知道的...

+0

+1在Groovy – 2011-05-31 10:39:25

+0

写地道的Perl +1 @tim,漂亮的替代解决方案。 (Map)m.findRecursive('foo')是Groovy.lang,imo的一个很好的补充。 – virtualeyes 2011-05-31 10:51:19

+0

@virtual,我同意......也许想出一个DGM补丁,几个测试,并将它们提交给JIRA?可以把它变成1.8.2 – 2011-05-31 10:55:52