【问题标题】:Filtering elements based on condition and date filed根据条件和日期过滤元素
【发布时间】:2021-02-11 13:26:33
【问题描述】:

我正在尝试根据以下条件过滤我的列表。

检查是否有重复的nameemployee 字段的记录。如果有重复,则只保留 date 字段值为最新的元素,忽略其他重复值。

输入列表:

[{
    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"
}]

理想的输出:

[{
    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"
}]

我尝试了findAll() 方法,但无法获得想要的结果。

【问题讨论】:

  • 显示您的尝试以及失败的原因,以便我们为您提供帮助。

标签: java grails groovy filter


【解决方案1】:

你可以groupBynameemployee的子图然后找到 max date 在分组项的值中。例如

def data = [
    [a: 1, b: 2, c: 0],
    [a: 1, b: 2, c: 3],
    [a: 2, b: 3, c: 0],
]

data.groupBy{
    it.subMap(["a", "b"])
}.collect{ k, v -> 
    k + [c: v*.c.max()] 
}
// -> [[a:1, b:2, c:3], [a:2, b:3, c:0]]

【讨论】:

    【解决方案2】:

    一个简单的inject 会有所帮助:

    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
    

    打印

    [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]
    

    【讨论】:

      【解决方案3】:

      作为一个选项,您可以将初始列表收集为嵌套地图。 例如,首先您可以按名称对记录进行分组。然后按员工分组。最终,您将获得以下 Map。 现在您可以通过地图中的键和列表中的最新日期来获取记录。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-10-24
        • 2011-12-04
        • 2018-05-17
        • 2021-02-05
        • 2021-12-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多