Groovy - 按属性排序,然后按原始列表的索引排序

时间:2017-04-04 22:03:05

标签: groovy

我试图先按属性排序列表,然后按元素的原始位置排序。所以

[[primaryProperty:2,foo:a],[primaryProperty:1,foo:c],[primaryProperty:1,foo:b]]

会变成:

[[primaryProperty:1,foo:c],[primaryProperty:1,foo:b],[primaryProperty:2,foo:a]]

我无法向地图添加属性(例如" currentIndex")。有这样的属性是我可以使用的排序功能的一部分吗?类似的东西:

list.sort{ a, b ->
            Integer returnVal = b.primaryProperty <=> a.primaryProperty 
            if(returnVal==0) {
                return a.index <=> b.index 
            } else {
                return returnVal
            }
        }

我更喜欢以一种常规的方式做这件事,而不是在可能的情况下创建和排序包装器。

2 个答案:

答案 0 :(得分:0)

您可以尝试在比较器中使用indexOf()

def list = [[primaryProperty:2,foo:'a'],[primaryProperty:1,foo:'c'],[primaryProperty:1,foo:'b']]

 list = list.sort{ a, b ->
            Integer returnVal = a.primaryProperty <=> b.primaryProperty 
            if(returnVal==0) {
                return list.indexOf( a ) <=> list.indexOf( b ) 
            } else {
                return returnVal
            }
        }

  assert list.toString() == '[{primaryProperty=1, foo=c}, {primaryProperty=1, foo=b}, {primaryProperty=2, foo=a}]'

答案 1 :(得分:0)

虽然injecteer的答案可能会解决问题,但重复使用indexOf运算符会使其效率低下。我最终围绕列表创建了一个包装器,对包装器进行了排序,然后从结果列表中获取数据:

List wrapper = objList.withIndex().collect{ obj, index -> [obj: obj, index: index] }
wrapper.sort{ ... }
List sortedObjList = wrapper.collect{ it.obj }

它并不理想,因为它涉及创建一堆中间对象,但它完成了工作。