簡體   English   中英

如何使用遞歸閉包從groovy中的列表構建樹層次結構?

[英]how do I build a tree hierarchy from a list in groovy using recursive closure?

我在grails中定義了遞歸域類:

class Work {

  String code
  String title
  String description
  static hasMany = [subWorks:Work]
  static mappedBy = [subWorks: 'parentWork']

  Work getRootWork(){
    if(parentWork) return parentWork.getRootWork()
      else return this
  }

  boolean isLeafWork(){
    return subWorks.isEmpty()
  }

  boolean isRootWork(){
    return !parentWork
  }

我有一個Works列表,但層次結構尚未構建。 結構如下:

def works = [new Work(code:'A', title:'TitleA'), 
    new Work(code:'B', title:'TitleB'), 
    new Work(code:'A.1', title:'Titile A.1'), 
    new Work(code:'B.1', title:'Title B.1'),
    new Work(code:'B.2', title:'Title B.2'),
    new Work(code:'B.3', title:'Title B.3'), 
    new Work(code:'B.2.2', title:'Title B.2.2'),
    new Work(code:'B.2.3', title:'Title B.2.3'),
    new Work(code:'A.1.1', title:'Title A.1.1'),
    new Work(code:'A.1.2', title:'Title A.1.2'),]

我需要的是根據提示的代碼在這些作品之間建立層次關系。 例如A.1是A的第一個童工; B.1.1是B.1工作的第一個孩子,其父母是B工作。 我知道Groovy支持遞歸閉包來構建這種層次結構。 如何在Groovy官方文檔中使用Groovy遞歸閉包實現我的目標,例如JN2515 Fibonacci數字示例? 非常感謝!

像這樣...?

def root = new Work(code:'*', title:'ROOT')

def build 

build = { p, list ->
  list.groupBy{it.code.split('\\.').first()}.each{ el, sublist ->
    el = sublist[0]        
    el.parentWork = p
    if(sublist.size()>1){
        build(el, sublist[1..-1] )
    }
  }

}
build(root, works.sort{it.code.length()})

如果我沒有錯,即使在這個anonim形式可能會工作

def root = new Work(code:'*', title:'ROOT')

{ p, list ->
  list.groupBy{it.code.split('\\.').first()}.each{ el, sublist ->
    el = sublist[0]        
    el.parentWork = p
    if(sublist.size()>1){
      call(el, sublist[1..-1] )
    }
  }

}(root, works.sort{it.code.length()})

我對Grails有點生疏,但我似乎記得它以智能方式管理映射集合,這樣如果你這樣做: work1.parentWork = work2那么work1 in work2.subWorks將驗證。 如果是這種情況,您需要做的就是為每個工作設置parentWork ,並且您不需要為此進行任何復雜的計算: XYZ的父工作將是XY ,而X的父工作將是無:

def works = [new Work(code:'A', title:'TitleA'),
    new Work(code:'B', title:'TitleB'),
    new Work(code:'A.1', title:'Titile A.1'),
    new Work(code:'B.1', title:'Title B.1'),
    new Work(code:'A.1.1', title:'Title A.1.1')]

def worksByCode = works.collectEntries { [it.code, it] }

works.each {
    if (it.code.contains('.')) {
        def parentCode = it.code[0..it.code.lastIndexOf('.') - 1]
        it.parentWork = worksByCode[parentCode]
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM