Question

I am new to groovy Lists, and I have list as shown below:

Class File{
 String name 
 int type
 int revision
}

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

I want the fileList to have the latest files

  1. It should not have the items of same type
  2. It should have the highest revision files means, if two or more files have the same type then the list must have the single file with the highest revision.

How do I do this in Groovy?

Was it helpful?

Solution

You can use Collection#groupBy to create a map with an entry for each unique file name. You can then use Map#collect to iterate over the contents of this map and create the list you want. The map's values will be a list of instances of File, so Collection#max will let you search for the one with the highest revision number.

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

I'm not sure what you meant when you said that the list should not have items of the same type. You'll notice that if there are two instances of File with the same name and revision number but different types, this solution picks one arbitrarily.

OTHER TIPS

I'd suggest reading http://groovy.codehaus.org/groovy-jdk/java/util/Collection.html and http://groovy.codehaus.org/Collections

A very naive way of doing this would be to use the collect method as follows

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

You could write as part of your condition in the collect closure to return false for duplicate items, then you wouldn't have to call unique()

[EDIT] Thinking about the problem you are faced with, you actually wouldn't want to use the above methods. Use the each method to iterate through your values. As I said, this is a naive way to complete your task, you may want to look into a good recursive method that piggy-backs off a sorting algorithm.

This is a naive example using some of Justin Piper's code. Read through those APIs I posted as well as the List JDK. You will definately be able to make a more efficient method. This code should give you a good idea of how groovy works and what can be done with closures.

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)
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top