如何按现有属性对列表进行排序 [英] How to sort a list by existing properties

查看:184
本文介绍了如何按现有属性对列表进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



  gVsort {it.name} 

如果存在,我如何根据名称对其进行排序,如果不存在,我想对它进行排序按标题。如果两者都存在,我想首先按名称和标题排序。

我不是Groovy编码器,所以非常感谢您的帮助。 / p>

解决方案

我不确定我是否正确理解您的问题。也许像这样的东西就是你要找的东西:

  def things = [
[name:'aaa', title:'222'],
[name:'aaa',title:'333'],
[title:'222'],
[title:'111'],
[名称:'bbb',标题:'111'],
[标题:'333'],
[名称:'aaa',标题:'111'],
]

things.sort {a,b - >
//按名称和标题进行比较。
a.name< => b.name?:a.title< => b.title
}

assert things == [
[title:'111'],
[title:'222'],
[标题:'333'],
[name:'aaa',title:'111'],
[name:'aaa',title:'222'],
[name: 'aaa',标题:'333'],
[名称:'bbb',标题:'111'],
]

看起来无辜的比较函数里面发生了什么实际上是Groovy语法中很多魔术。但不要太难追踪。

首先, > sort 方法正在被一个充当比较器的二进制函数调用(即接受两个参数a和b并返回-1如果a b并且0如果a == b)。

这个匿名函数: {a,b - > a.name< => b.name?:a.title< => b.title} 使用飞船运营商< => ...这是一个太空船的人!)首先比较a和b的名字。



名称相等(或两者都为空),则 a.name< => b.name 是0,它在 Elvis operator ?: ...想象它是一个笑脸),那么 a的结果.title< =>返回b.title



否则,如果名称比较的结果不是0,那么在Elvis运算符中如实评估并返回该值。



这一切都考虑到您可以将空值与字符串进行比较,并且'any string'> ('any string'< => null == 1 )。



所以最终的结果是没有名字的元素是第一个,按标题排序,然后名称和标题的元素首先按名称排序,然后按标题排序。



我希望那正是您要找的。如果您希望对排序后的元素进行不同的排序,请在评论中澄清:)

更新



还有一个不是很有记录的 OrderBy 可以在这种情况下使用的对象:

 东西。对新的OrderBy进行排序([{it.name},{it.title}])


I am using this line here to sort a list based on the object's name.

g.V.sort{it.name}

How do I sort it based on "name" if it exists, if not, I wanna sort it by "title". If both exist I want to first sort by "name" and then by "title".

I'm not a Groovy coder so thanks for the help in advance.

解决方案

I'm not sure I understand your question correctly. Maybe something like this is what you are looking for:

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'],
]

What's happening inside that seemingly innocent comparison function is actually quite a lot of Groovy syntax magic. But it's not too difficult to follow.

First, the sort method is being invoked with a binary function that acts as a comparator (i.e. takes two arguments, a and b and returns -1 if a < b, 1 if a > b and 0 if a == b).

This anonymous function: { a, b -> a.name <=> b.name ?: a.title <=> b.title } uses the "spaceship operator" (<=>... that's a spaceship man!) to first compare a and b by names.

If the names are equal (or both null), then the result of a.name <=> b.name is 0, which evaluates falsely in the "Elvis operator" (?:... imagine it as a smiley), so then the result of a.title <=> b.title is returned.

Otherwise, if the result of the name comparison is not 0, then that evaluates truthfully in the Elvis operator and that value is returned.

This is all taking into consideration that you can compare null values with strings and that 'any string' > null always holds (which is the same as saying that 'any string' <=> null == 1).

So the final result is that elements with no name are first and sorted by title, and then the elements with name and title are ordered first by name and then by title.

I hope that was what you were looking for. If you were expecting a different ordering of the sorted elements feel free to clarify it in the comments :)

Update

There is also a not very documented OrderBy object that can be used in this case:

things.sort new OrderBy([{it.name}, {it.title}])

这篇关于如何按现有属性对列表进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆