在groovy中列出排序

时间:2014-10-19 17:52:27

标签: sorting groovy

我有一个图书清单,其中包含图书ID,出版商名称,联系电话,地址,图书发布日期和图书状态(有效,已删除,已暂停)。我想根据以下标准对列表进行排序:

  1. 按激活日期排序
  2. 将发布商名称从A到Z
  3. 排序
  4. 如果在同一日期范围内有两个发布商名称,则应根据图书状态对其进行排序,并且订单应处于有效状态>暂停>删除(这不是字母排序)
  5. 例如,结果应为:

    Activation Date: 18.10.2014
    Test Book, ABC publisher, active
    Test Book2, ABC publisher, suspended
    Book3, XXYYBB publisher, active 
    
    Activation Date: 19.10.2014
    Test Book5, XXYYBB publisher, deleted
    Test Book3, ZZZZ publisher, active
    Test Book4, ZZZZ publisher, suspended
    

    我的示例代码:

    booklist.sort{ x,y ->
      x.activateDate <=> y.activateDate ?: x.publisherName <=> y.publisherName
    }
    

    如何对书籍状态进行第三次手动检查?

2 个答案:

答案 0 :(得分:3)

解决方案1:enum

如果状态确实限于给出的三个确切值,那么您可能已经在使用这样的东西:

enum BookStatus { active, suspended, deleted }

然后在Book课程中:

class Book {
    ...
    BookStatus status
}

由于Enum类已经具有自然排序顺序(声明顺序),因此您只需将另一个elvis(?:)子句添加到比较器闭包中:

booklist.sort { x, y ->
    x.activateDate <=> y.activateDate ?:
        x.publisherName <=> y.publisherName ?:
        x.status <=> y.status
}

解决方案2:状态排序List

参见@cfrick的解决方案

解决方案3:状态排序Map

与基于列表的解决方案相比,此解决方案只有几个小优势:

  • 通过LinkedHashMap的平均密钥搜索具有算法复杂度 O(1),而通过ArrayList的平均元素搜索具有 O(n)
  • statusOrder[x.status] <=> statusOrder[y.status]表达式比statusList.indexOf(x.status) <=> statusList.indexOf(y.status)
  • 简单得多

此处Book.status被假定为String

final statusOrder = [ active:0, suspended:1, deleted:2 ].asImmutable()
booklist.sort { x, y ->
    x.activateDate <=> y.activateDate ?:
            x.publisherName <=> y.publisherName ?:
            statusOrder[x.status] <=> statusOrder[y.status]
}

如果由于某种原因我无法使用Enum解决方案,我可能会使用List解决方案,除非有大量(超过20?)个状态值,在这种情况下我会使用Map解决方案。

答案 1 :(得分:2)

如果这些是字符串,您可以使用列表来定义重要性,然后使用ufo-operator

在此列表中使用索引
final order = ['active','suspended','deleted']

def l = [
        [status: 'deleted'],
        [status: 'active'],
        [status: 'suspended'],
        [status: 'active'],
        [status: 'suspended'],
]

println l.sort{ a,b -> order.indexOf(a.status) <=> order.indexOf(b.status) }
// -> [[status:active], [status:active], [status:suspended], [status:suspended], [status:deleted]]