Search code examples
javagrailsgroovyfilter

Filtering elements based on condition and date filed


I am trying to filter my list based on the below condition.

check if any records with duplicate name and employee fields. If it has duplicates then keep only the element whose date field value is latest and ignoring other duplicate values.

input list:

[{
    name: "Bob",
    employee: "yes",
    date: "10/12/2020"
},
{
    name: "John",
    employee: "no",
    date: "14/12/2020"
},
{
    name: "Bob",
    employee: "yes",
    date: "14/12/2020"
},
{
    name: "Doe",
    employess: "yes",
    date: "10/01/2020"
},
{
    name: "Bob",
    employess: "yes",
    date: "09/12/2020"
},
{
    name: "Doe",
    employee: "yes",
    date: "01/12/2019"
},
{
    name: "Bob",
    employee: "no",
    date: "01/12/2019"
}]

Desirable output:

[{
    name: "Bob",
    employee: "yes",
    date: "14/12/2020"
},
{
    name: "John",
    employee: "no",
    date: "14/12/2020"
},
{
    name: "Bob",
    employee: "no",
    date: "01/12/2019"
},
{
    name: "Doe",
    employess: "yes",
    date: "10/01/2020"
}]

I tried with findAll() method but not able to get desired results.


Solution

  • A simple inject would help:

    def list = [[
        name: "Bob",
        employee: "yes",
        date: "10/12/2020"
    ],
    [
        name: "John",
        employee: "no",
        date: "14/12/2020"
    ],
    [
        name: "Bob",
        employee: "yes",
        date: "14/12/2020"
    ],
    [
        name: "Doe",
        employee: "yes",
        date: "10/01/2020"
    ],
    [
        name: "Bob",
        employee: "yes",
        date: "09/12/2020"
    ],
    [
        name: "Doe",
        employee: "yes",
        date: "01/12/2019"
    ],
    [
        name: "Bob",
        employee: "no",
        date: "01/12/2019"
    ]]
    
    def sdf = new java.text.SimpleDateFormat('dd/MM/yyyy')
    
    def result = list.inject( [:] ){ res, curr ->
      Date date = sdf.parse curr.date
      String key = curr.name + '_' + curr.employee
      if( res[ key ]?.date < date ){
        res[ key ] = curr + [ date:date ]
      }
      res
    }.values().collect{ it + [ date:sdf.format( it.date ) ] }.join('\n')
    
    println result
    

    prints

    [name:Bob, employee:yes, date:14/12/2020]
    [name:John, employee:no, date:14/12/2020]
    [name:Doe, employee:yes, date:10/01/2020]
    [name:Bob, employee:no, date:01/12/2019]