在Groovy中分组和排序嵌套集合 [英] Grouping and sorting nested collections in Groovy

查看:140
本文介绍了在Groovy中分组和排序嵌套集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下POGO:

  class Widget {
字符串名称
整数次序
//许多其他字段

Widget(整数顺序){
super()
this.order =订单
}
}

我有一个 List< Widget> 把它们放到一个 List< Set< Widget>>< / code>中,按顺序字段分组。因此,如果我有3个小部件,它们具有以下各个订单: {3,1,2} 那么我将有一个外部 List 大小为3,并且该列表中的每个元素都是大小为1的 Set 。我可以通过以下代码手动生成此代码:



'pre> 窗口小部件W1 =新小工具(3)
的widget W2 =新小工具(1)
的widget W3 =新小工具(2)

//现在通过手动排序对它们进行排序:
Set< Widget> firstOrderWidgets = []
firstOrderWidgets<< w2 // order = 1

Set< Widget> secondOrderWidgets = []
secondOrderWidgets<< w3 // order = 2

Set< Widget> thirdOrderWidgets = []
thirdOrderWidgets<< w1 // order = 3

List< Set< Widget>> sortedCorrectly = []
sortedCorrectly<< firstOrderWidgets //所有小部件w / order = 1
sortedCorrectly<< secondOrderWidgets //所有小部件w / order = 2
sortedCorrectly<< thirdOrderWidgets //所有部件w / order = 3

所以这里的想法是, unsorted / ungrouped List< Widget> 可能非常大,并且很多小部件可能包含相同的顺序。我们希望将所有小部件order = 1,order = 2等)放入同一个内部 Set 中,然后将这些集合添加到外部 List 按升序排列。因此,如果我们要在上面的例子中添加第四个小部件:

 小工具w4 =新小工具(2)

此小工具属于另一个二阶小工具:

 组<窗口小部件> secondOrderWidgets = [] 
secondOrderWidgets<< w3 // order = 2
secondOrderWidgets<< w4 // order = 2

所以我试着编写一个方法,它取列出< Widget> 作为输入,按顺序进行分组,然后按升序对这些组/集进行排序。 顺序字段保证为非空,但可以是任何有效的正整数(1+)。我最好的尝试是导致各种运行时/动态异常:

 列表< Set< Widget>> sortWidgets(List< Widget> toSort){
def groupedByOrder = toSort.groupBy({widget - > widget.order})

groupedByOrder = groupedByOrder.sort()

List< Set< Widget>> sortedList = []
groupedByOrder.each {order,widgets - >
sortedList<<新的HashSet(小工具)
}

sortedList
}

任何人都可以找到我要去的地方吗?

我无法设法重现您的错误。这可能是由于等于 hashCode 在您的 Widget 类。我设法使用 @Canonical

  @ groovy.transform.Canonical 
class Widget {
int order
String toString(){Widget(order = $ order,$ {hashCode()})}
}

widget = {新小工具(order:it)}

w1 =小工具(3)
w2 =小工具(1)
w3 =小工具(2)
w4 =小工具2)
W5 =插件(2)

allWidgets = [W4,W1,W2,W5,W3]

DEF sortWidgets(小部件){
widgets.sort(false){it.order} .groupBy {it.order} .values()as List
}

assert sortWidgets(allWidgets)== [
[w2],
[w3,w4,w5],
[w1]
]


I have the following POGO:

class Widget {
    String name
    Integer order
    // lots of other fields

    Widget(Integer order) {
        super()
        this.order = order
    }
}

I have a List<Widget> and am trying to put them into a List<Set<Widget>> where they are grouped by the order field. So if I have 3 widgets with the following respective orders: { 3, 1, 2 } then I would have an outer List of size 3 and each element in that list would be a Set of size 1. I could manually produce this in code via:

Widget w1 = new Widget(3)
Widget w2 = new Widget(1)
Widget w3 = new Widget(2)

// Now sort them by order manually:
Set<Widget> firstOrderWidgets = []
firstOrderWidgets << w2 // order = 1

Set<Widget> secondOrderWidgets = []
secondOrderWidgets << w3 // order = 2

Set<Widget> thirdOrderWidgets = []
thirdOrderWidgets << w1 // order = 3

List<Set<Widget>> sortedCorrectly = []
sortedCorrectly << firstOrderWidgets    // All widgets w/ order = 1
sortedCorrectly << secondOrderWidgets   // All widgets w/ order = 2
sortedCorrectly << thirdOrderWidgets    // All widgets w/ order = 3

So the idea here is that the "unsorted/ungrouped" List<Widget> could be quite large, and many widgets could contain the same order. We want to group all widgets with the same order (order = 1, order = 2, etc.) into the same inner Set and then add those sets to the outer List in ascending order. So if we were to add a 4th widget to the example above:

Widget w4 = new Widget(2)

This widget belongs with the other 2nd order widget:

Set<Widget> secondOrderWidgets = []
secondOrderWidgets << w3 // order = 2
secondOrderWidgets << w4 // order = 2

So I'm trying to write a method that take List<Widget> as input, groups them by order and then sorts those groups/sets in ascending order. The order field is guaranteed to be non-null, but could be any valid positive (1+) integer. My best attempt is causing all sorts of runtime/dynamic exceptions:

List<Set<Widget>> sortWidgets(List<Widget> toSort) {
  def groupedByOrder = toSort.groupBy({ widget -> widget.order })

  groupedByOrder = groupedByOrder.sort()

  List<Set<Widget>> sortedList = []
  groupedByOrder.each { order, widgets ->
      sortedList << new HashSet(widgets)
  }

    sortedList
}

Can anyone spot where I'm going awry?

解决方案

I couldn't manage to reproduce your error. It can happen due to how equals and hashCode are implemented in your Widget class. I managed to get a working example using @Canonical:

@groovy.transform.Canonical
class Widget {
    int order
    String toString() { "Widget(order=$order, ${hashCode()})" }
}

widget = { new Widget(order: it) }

w1 = widget(3)
w2 = widget(1)
w3 = widget(2)
w4 = widget(2)
w5 = widget(2)

allWidgets = [w4, w1, w2, w5, w3]

def sortWidgets(widgets) {
    widgets.sort(false) { it.order }.groupBy { it.order }.values() as List
}

assert sortWidgets(allWidgets) == [
    [w2],
    [w3, w4, w5],
    [w1]
] 

这篇关于在Groovy中分组和排序嵌套集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆