5

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
  }

作品一覧はありますが、まだ階層構造が構築されていません。構造は次のようになります。

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 の公式ドキュメントにある JN2515 フィボナッチ数の例など、Groovy の再帰クロージャーを使用して目標を達成するにはどうすればよいですか? どうもありがとう!

4

2 に答える 2

3

このような...?

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()})

この匿名フォームでも私が間違っていなければうまくいくかもしれません

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()})
于 2013-04-12T12:06:51.803 に答える
1

私はGrailsに少し慣れていませんが、マッピングされたコレクションをインテリジェントな方法で管理していたことを覚えているようwork1.parentWork = work2ですwork1 in work2.subWorks。その場合、parentWork作業ごとに を設定するだけでよく、複雑な計算を行う必要はありません: の親作業はX.Y.ZになりX.Y、 の親作業はXnone になります:

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]
    }
}
于 2013-04-12T12:51:18.893 に答える