0

私はグルーヴィーなリストに不慣れで、以下に示すようなリストを持っています:

Class File{
 String name 
 int type
 int revision
}

def fileList = [File1, File2, File3,....]

fileList最新のファイルが必要です

  1. 同じタイプのアイテムがあってはなりません
  2. 2 つ以上のファイルが同じタイプである場合、リストには最高のリビジョンを持つ単一のファイルが含まれている必要があります。

Groovyでこれを行うにはどうすればよいですか?

4

2 に答える 2

3

を使用Collection#groupByして、一意のファイル名ごとにエントリを持つマップを作成できます。次に、 を使用Map#collectして、このマップの内容を繰り返し処理し、必要なリストを作成できます。マップの値は のインスタンスのリストになるFileためCollection#max、リビジョン番号が最も大きいものを検索できます。

class File {
    String name
    int type
    int revision

    String toString() { "File(name: $name; type: $type; revision: $revision)" }
}

final files = [
    new File(name: 'foo', type: 0, revision: 0),
    new File(name: 'bar', type: 0, revision: 0),
    new File(name: 'bar', type: 0, revision: 1),
    new File(name: 'baz', type: 0, revision: 0),
    new File(name: 'baz', type: 0, revision: 1),
    new File(name: 'baz', type: 1, revision: 1),
]

final result = files.groupBy { it.name }
             . collect { name, revisions -> revisions.max { it.revision } }

リストに同じタイプのアイテムを含めてはならないと言ったときの意味がわかりません。名前とリビジョン番号が同じでタイプが異なる のインスタンスが 2 つある場合File、このソリューションは任意に 1 つを選択します。

于 2012-08-31T19:42:25.470 に答える
0

http://groovy.codehaus.org/groovy-jdk/java/util/Collection.htmlhttp://groovy.codehaus.org/Collectionsを読むことをお勧め します

これを行う非常に単純な方法は、次のように collect メソッドを使用することです。

fileList.collect { file ->
  //your condition
}.unique { file ->
  //code that determines uniqueness
}

collect クロージャーの条件の一部として記述して、重複するアイテムに対して false を返すことができます。その後、unique() を呼び出す必要はありません。

[編集] 直面している問題について考えると、実際には上記の方法を使用したくないでしょう。each メソッドを使用して、値を反復処理します。私が言ったように、これはあなたのタスクを完了するための単純な方法です.ソートアルゴリズムをピギーバックする良い再帰的方法を調べたいと思うかもしれません.

[編集] 同じ質問に対する 2 つの回答をマージする (効率設計の考慮事項)

これは、Justin Piper のコードの一部を使用した素朴な例です。私が投稿した API と List JDK を読んでください。間違いなく、より効率的な方法を作成できるようになります。このコードは、groovy がどのように機能し、クロージャーで何ができるかについての良いアイデアを提供するはずです。

class File {
    String name
    int type
    int revision

    String toString() { "File(name: $name; type: $type; revision: $revision)" }
}

def files = [
  new File(name: 'First Type2', type: 2, revision: 0),
  new File(name: 'First Type0', type: 0, revision: 1),
  new File(name: 'First Type1', type: 1, revision: 1),
  new File(name: 'Second Type0', type: 0, revision: 0),
  new File(name: 'Second Type1', type: 2, revision: 1),
  new File(name: 'Second Type2', type: 1, revision: 1),
]
//This will hold the final set of files according to the logic in the next each()
def selectedFiles = [:] 
files.each { file ->
     //Overwrite the value associated with the key, which is the type depending on the logic - we only keep 1 of each type
     if(selectedFiles[file.type]){
         if(selectedFiles[file.type].revision < file.revision){
            selectedFiles[file.type] = file
         }
     }
     else{
         //This type never existed, so just write the file as the value
         selectedFiles[file.type] = file
     }
}

selectedFiles.each { type, file ->
    println(file)
}
于 2012-08-31T12:48:17.433 に答える