Groovy list.sort由第一,第二和第三个元素组成

时间:2009-09-23 18:00:16

标签: sorting groovy

我有一个常见的清单清单,即

list = [[2, 0, 1], [1, 5, 2], [1, 0, 3]]

我想按第一个元素的顺序排序,然后是第二个元素,然后是第三个元素。

预期

assert list == [[1, 0, 3], [1, 5, 2], [2, 0, 1]]

我从list = list.sort{ a,b -> a[0] <=> b[0] }开始,但只对第一个元素进行排序。你是怎么完成的?

由于

7 个答案:

答案 0 :(得分:26)

您应该能够以相反的顺序迭代所需的排序:

list = [[2, 0, 1], [1, 5, 2], [1, 0, 3]]

list = list.sort{ a,b -> a[2] <=> b[2] }
list = list.sort{ a,b -> a[1] <=> b[1] }
list = list.sort{ a,b -> a[0] <=> b[0] }

assert list == [[1, 0, 3], [1, 5, 2], [2, 0, 1]]

每个都应该覆盖前一个,以保持组合排序的完整性。


您还可以使用Elvis operator, ?:按顺序将它们链接起来,当前一个相等时,将遵循下一个比较(<=>返回0):

list.sort { a,b -> a[0] <=> b[0] ?: a[1] <=> b[1] ?: a[2] <=> b[2] }

答案 1 :(得分:8)

如果你想对任意(虽然是同质的)长度的数组进行排序,你可以使用它,它将在一次传递中完成:

def list = [[2, 0, 1], [1, 5, 2], [1, 0, 3]]

list.sort { a, b -> 
    for (int i : (0..<a.size())) {
        def comparison = (a[i] <=> b[i])
        if (comparison) return comparison
    } 
    return 0
}

assert list == [[1, 0, 3], [1, 5, 2], [2, 0, 1]]

答案 2 :(得分:5)

以下是使用Groovy的SpaceshipElvis运算符的另一种方法:

​def list = [[2, 0, 1], [1, 5, 2], [1, 0, 3]]

list.sort { a, b ->
   a[0] <=> b[0] ?: a[1] <=> b[1] ?: a[2] <=> b[2]
}

assert list == [[1, 0, 3], [1, 5, 2], [2, 0, 1]]​

来源:Groovier way of sorting over multiple fields in a list of maps in groovy

答案 3 :(得分:4)

你可以使用kobo-commons的CollectionUtils库。

http://wiki.github.com/kobo/kobo-commons/sort-by-multiple-keys

import org.jggug.kobo.commons.lang.CollectionUtils

CollectionUtils.extendMetaClass()


list = [[2, 0, 1], [1, 5, 2], [1, 0, 3]]
list = list.sort{ [ it[0], it[1], it[2] ]} // sort by multiple keys
assert list == [[1, 0, 3], [1, 5, 2], [2, 0, 1]]

list2 = [ [name:"a", age:13], [name:"a",age:15], [name:"b", age:13] ]
list2 = list2.sort{[it.name, it.age] } // sort by name and age
assert list2 == [[name:"a", age:13], [name:"a", age:15], [name:"b", age:13]]

答案 4 :(得分:2)

完成Groovy方式,无论子列表的大小如何:

ll2.sort { l1, l2 ->
  e1e2 = [l1, l2].transpose().find { e1, e2 ->
      e1 != e2
  }
  e1e2 ? e1e2[0] <=> e1e2[1] : 0
}

答案 5 :(得分:0)

这是我提出的,而不是我想的最常貌的方式..

list = list.sort{ a,b -> 
    if(a[0].compareTo(b[0]) == 0) {
        if(a[1].compareTo(b[1]) == 0) {
            return a[2].compareTo(b[2]);
        } else {
            return a[1].compareTo(b[1]);
        }
    } else {
        return a[0].compareTo(b[0]);
    }
}

答案 6 :(得分:0)

您可以在一行中完成:

list.sort { String.format('%010d%010d%010d', it[0], it[1], it[2]) }