我在这里使用这一行来根据对象的名称对列表进行排序。
g.V.sort{it.name}
如果存在,我如何根据“名称”对其进行排序,如果不存在,我想按“标题”对其进行排序。如果两者都存在,我想首先按“名称”排序,然后按“标题”排序。
我不是Groovy程序员,所以感谢您的帮助。
答案 0 :(得分:13)
我不确定我是否理解你的问题。也许这就是你要找的东西:
def things = [
[name: 'aaa', title: '222'],
[name: 'aaa', title: '333'],
[title: '222'],
[title: '111'],
[name: 'bbb', title: '111'],
[title: '333'],
[name: 'aaa', title: '111'],
]
things.sort { a, b ->
// Compare by name and then by title.
a.name <=> b.name ?: a.title <=> b.title
}
assert things == [
[title: '111'],
[title: '222'],
[title: '333'],
[name: 'aaa', title: '111'],
[name: 'aaa', title: '222'],
[name: 'aaa', title: '333'],
[name: 'bbb', title: '111'],
]
在看似无辜的比较函数中发生的事实实际上是很多Groovy语法魔法。但这并不难理解。
首先,使用充当比较器的二进制函数调用sort
方法(即接受两个参数a和b,如果&lt; b,则返回-1,如果&gt; b则返回1 0如果a == b)。
这个匿名函数:{ a, b -> a.name <=> b.name ?: a.title <=> b.title }
使用“spaceship operator”(<=>
......这是太空飞船!)首先按名称比较a和b。
如果名称相等(或两者都为空),则a.name <=> b.name
的结果为0,其在“Elvis operator”(?:
中错误地评估...将其想象为一个笑脸),然后返回a.title <=> b.title
的结果。
否则,如果名称比较的结果不是0,那么在Elvis运算符中如实评估并返回该值。
这一切都考虑到你可以将空值与字符串进行比较,'any string' > null
始终保持(这与'any string' <=> null == 1
}相同。
所以最后的结果是没有名字的元素首先按标题排序,然后名称和标题的元素首先按名称排序,然后按标题排序。
我希望那就是你要找的东西。如果您期望排序元素的不同排序,请随时在评论中澄清它:)
在这种情况下还可以使用一个没有记录的OrderBy
对象:
things.sort new OrderBy([{it.name}, {it.title}])
答案 1 :(得分:5)
您可以使用Comparator
对收藏品进行排序。
g.V.sort { a, b ->
a.name <=> b.name ?: a.title <=> b.title
}
答案 2 :(得分:0)
这是我完全未经测试的努力,可能充满了错误
def comparator = {o1, o2 ->
// wording of question suggests title will always exist, if not, add more hasProperty checks
def diff = o1.title <=> o2.title
if (o1.hasProperty('name') && o2.hasProperty('name')) {
def nameDiff = o1.name <=> o2.name
if (nameDiff != 0) {
diff = nameDiff
}
}
diff
} as Comparator
def someList = []
// populate the list...
someList.sort(comparator)