【问题标题】:Sort list of maps based on multiple keys [closed]基于多个键对地图列表进行排序[关闭]
【发布时间】:2017-09-27 20:32:06
【问题描述】:

我有一个ListMaps,看起来像这样:

[{type=UNL,date=20170606,publication=ECC,boNumber=34,value=500}
{type=UNP,date=20190807,publication=ECD,boNumber=24,value=100}
{type=UNA,date=20170606,publication=ECC,boNumber=34,value=400}
{type=UNC,date=20170606,publication=ECC,boNumber=34,value=300}
{type=UNF,date=20190807,publication=ECD,boNumber=24,value=200}]

对我来说最重要的字段是date,publication,boNumber 的值,例如20170606 ECC 34。我想使用这三个字段对这个List 进行排序。

预期结果

[{type=UNL,date=20170606,publication=ECC,boNumber=34,value=500}
{type=UNA,date=20170606,publication=ECC,boNumber=34,value=400}
{type=UNC,date=20170606,publication=ECC,boNumber=34,value=300}
{type=UNP,date=20190807,publication=ECD,boNumber=24,value=100}
{type=UNF,date=20190807,publication=ECD,boNumber=24,value=200}]

如何在 mule 中使用 groovy、dataweave 或 Java 来实现。

【问题讨论】:

  • 不幸的是,您的问题归结为“请有人帮我解决这个问题”。但我们不将此类请求视为本网站范围内的问题。请仔细阅读this 以了解原因。然后考虑删除这个问题并在这个社区的范围内提出一个新的、更精确的问题。或者,您可以修改和改进这个问题。谢谢!
  • “最佳”以哪种方式?真的不清楚你希望我们在这里做什么。你的问题太笼统和不具体。提示:尝试自己 - 当您遇到问题时,提交您的代码,我们会从那里提供帮助。
  • @GhostCat 为什么“如何使用地图的多个键对地图列表进行排序”不是一个合适的问题?它并不是很广泛和不具体。还是您只是不喜欢“最佳方法”这个词?
  • @Vampire 因为那个“最好的方法”这个词?这为无休止的讨论打开了空间。有许多不同的维度,其中一个解决方案可能是最好的......或者不是那么好。

标签: java arraylist groovy mule dataweave


【解决方案1】:

你要的是.sort { [it.date, it.publication, it.boNumber] }

def listOfMaps = [[type:'UNL',date:20170606,publication:'ECC',boNumber:34,value:500],
[type:'UNP',date:20190807,publication:'ECD',boNumber:24,value:100],
[type:'UNA',date:20170606,publication:'ECC',boNumber:34,value:400],
[type:'UNC',date:20170606,publication:'ECC',boNumber:34,value:300],
[type:'UNF',date:20190807,publication:'ECD',boNumber:24,value:200]]

listOfMaps
    .each { println it }
println()
listOfMaps
    .sort { [it.date, it.publication, it.boNumber] }
    .each { println it }

例如输出

[type:UNL, date:20170606, publication:ECC, boNumber:34, value:500]
[type:UNP, date:20190807, publication:ECD, boNumber:24, value:100]
[type:UNA, date:20170606, publication:ECC, boNumber:34, value:400]
[type:UNC, date:20170606, publication:ECC, boNumber:34, value:300]
[type:UNF, date:20190807, publication:ECD, boNumber:24, value:200]

[type:UNL, date:20170606, publication:ECC, boNumber:34, value:500]
[type:UNA, date:20170606, publication:ECC, boNumber:34, value:400]
[type:UNC, date:20170606, publication:ECC, boNumber:34, value:300]
[type:UNP, date:20190807, publication:ECD, boNumber:24, value:100]
[type:UNF, date:20190807, publication:ECD, boNumber:24, value:200]

【讨论】:

  • date 不是整数时,您的解决方案会产生不同的结果 - gist.github.com/wololock/16a895091e359ecff05a38df96515758 此字段看起来更像是格式为yyyyMMdd 的日期字符串
  • @SzymonStepniak 好吧,实际上要求只是匹配datepublicationboNumber 的元素在结果列表中。
  • 没错,但它不会改变这样一个事实,即您的解决方案会产生不确定的结果。它仅证明您的代码有问题 - Integer 及其 String 表示应该以相同的方式排序。
  • @SzymonStepniak 好吧,“错误”是,这种组相互对抗是随机的,因为比较列表并且没有定义明确的排序。但它完全满足线条应该在一起的要求。没有人要求可重复的排序。
  • @tvelykyy 正如你在docs.groovy-lang.org/docs/groovy-2.4.7/html/groovy-jdk/java/… 看到的那样,如果你给它的闭包有一个参数(在这种情况下是隐含的it),你指定比较标准。这意味着所有三个元素都相同的地图被排序在一起。
【解决方案2】:

您可以使用 Dataweave 来实现这一点

%dw 1.0
%output application/json
---
payload orderBy ($.date ++ $.publication ++ $.boNumber)

希望这会有所帮助。

【讨论】:

    【解决方案3】:

    Groovy 的解决方案如下所示:

    List list = [[type: 'UNL', date: '20170606', publication: 'ECC', boNumber: 34, value: 500],
                 [type: 'UNP', date: '20190807', publication: 'ECD', boNumber: 24, value: 100],
                 [type: 'UNA', date: '20170606', publication: 'ECC', boNumber: 34, value: 400],
                 [type: 'UNC', date: '20170606', publication: 'ECC', boNumber: 34, value: 300],
                 [type: 'UNF', date: '20190807', publication: 'ECD', boNumber: 24, value: 200]]
    
    List sorted = list.sort { a,b ->
        a.date == b.date ?
                (a.publication == b.publication ?
                        a.boNumber <=> b.boNumber :
                        a.publication <=> b.publication) :
                a.date <=> b.date
    }
    
    sorted.each { println it }
    

    传递给.sort() 方法的闭包执行以下操作:

    • 首先按date字段排序
    • 如果两个日期相等,它会检查 publication 字段是否相等
    • 然后如果两个publication 字段相等,则按boNumber 排序
    • 否则按publication排序

    输出

    [type:UNL, date:20170606, publication:ECC, boNumber:34, value:500]
    [type:UNA, date:20170606, publication:ECC, boNumber:34, value:400]
    [type:UNC, date:20170606, publication:ECC, boNumber:34, value:300]
    [type:UNP, date:20190807, publication:ECD, boNumber:24, value:100]
    [type:UNF, date:20190807, publication:ECD, boNumber:24, value:200]
    

    【讨论】:

    • 只是好奇,您认为您的解决方案是否比像我的解决方案中仅提取具有三个字段的排序键更好?
    • @Vampire 我不会说它更好。仅当 date 字段是整数时,您的解决方案才会产生正确的结果。如果你用字符串替换整数(date 字段看起来像一个包含yyyyMMdd 日期字符串的字段)那么你的解决方案就坏了 - gist.github.com/wololock/16a895091e359ecff05a38df96515758
    猜你喜欢
    • 1970-01-01
    • 2019-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-31
    • 2018-03-24
    • 2019-03-31
    • 1970-01-01
    相关资源
    最近更新 更多