繁体   English   中英

在Groovy中对嵌套集合进行分组和排序

[英]Grouping and sorting nested collections in Groovy

我有以下POGO:

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

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

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

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

因此,这里的想法是“未排序/未分组”的List<Widget>可能会很大,并且许多小部件可能包含相同的顺序。 我们希望将具有相同顺序(order = 1,order = 2等)的所有小部件分组到相同的内部Set ,然后将这些集合按升序添加到外部List中。 因此,如果我们要在上面的示例中添加第四个小部件:

Widget w4 = new Widget(2)

此小部件与另一个二阶小部件一起属于:

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

因此,我试图编写一种方法,将List<Widget>作为输入,按order它们进行分组,然后按升序对这些组/集进行排序。 保证order字段为非空值,但可以是任何有效的正(1+)整数。 我的最佳尝试是导致各种运行时/动态异常:

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
}

谁能发现我要去哪里?

我无法重现您的错误。 由于在Widget类中如何实现equalshashCode因此可能会发生这种情况。 我设法得到一个使用@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]
] 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM