2012-08-31 46 views
0

我是新來的Groovy列表,我有表,如下圖所示:如何循環列表,並刪除符合條件的商品,以創建一個新的列表

Class File{ 
String name 
int type 
int revision 
} 

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

我想fileList有最新的文件

  1. 它不應該有相同類型
  2. 的項目應該具有的最高版本的文件意味着,如果兩個或多個文件具有相同的類型,那麼列表必須與最高版本的單個文件。

如何在Groovy中執行此操作?

回答

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

我不確定你說的是什麼意思,當你說列表不應該有相同類型的項目。你會注意到,如果File有兩個具有相同名稱和修訂號但類型不同的實例,則此解決方案會任意選取一個。

0

我建議你閱讀 http://groovy.codehaus.org/groovy-jdk/java/util/Collection.htmlhttp://groovy.codehaus.org/Collections

這樣做的一個非常簡單的方式是使用的收集方法如下

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

你可以寫爲作爲條件的一部分在收集關閉返回虛假的重複項目,那麼你將不必調用唯一()

[編輯]思考你遇到的問題,你實際上不想使用上述方法。使用每種方法遍歷你的值。正如我所說,這是一種天真的方式來完成您的任務,您可能想要查看一個很好的遞歸方法,甩掉排序算法。

+0

你能舉個例子嗎 – n92

0

這是一個天真的例子,使用了一些Justin Piper的代碼。通讀我發佈的 以及列表JDK的API。你肯定能夠做出更有效的方法。 這段代碼應該給你一個關於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) 
} 
相關問題