我正在使用这行代码根据对象名称对列表进行排序。
g.V.sort{it.name}
如果存在"name",我该如何基于它进行排序?如果不存在,我想按"title"排序。如果两者都存在,我想先按"name"排序,然后再按"title"排序。
我不是Groovy编码人员,所以提前感谢您的帮助。
我不确定我正确理解了你的问题。也许像这样的东西是你在寻找的:
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,如果a < b则返回-1,如果a > b则返回1,如果a == b则返回0)。
这个匿名函数:{ 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
的结果。'any string' > null
始终成立(这与说'any string' <=> null == 1
相同)。在这种情况下,还有一个不太被记录的OrderBy
对象可以使用:
things.sort new OrderBy([{it.name}, {it.title}])
Comparator
对集合进行排序。g.V.sort { a, b ->
a.name <=> b.name ?: a.title <=> b.title
}
这是我完全未经测试的努力,可能充满了错误。
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)