按数字(最高优先)然后按字母(字母顺序)对对象集合进行排序

Posted

技术标签:

【中文标题】按数字(最高优先)然后按字母(字母顺序)对对象集合进行排序【英文标题】:Sort a collection of objects by number (highest first) then by letter (alphabetical) 【发布时间】:2011-01-15 00:06:45 【问题描述】:

我正在构建一个小部件来显示奥运会的奖牌数。我有一个“国家”对象的集合,其中每个对象都有一个“名称”属性,以及用于奖牌数量的“金”、“银”、“铜”。

列表应该排序: 1.首先按奖牌总数 2.如果奖牌相同,按类型进行分类(金>银>铜,即两金>一金+一银) 3.如果奖牌和类型相同,按字母顺序排序

我正在用 ruby​​ 做这个,但我想语言并不重要。我确实想出了一个解决方案,但如果觉得必须有一个更优雅的方法来做到这一点。

这就是我所做的:

    使用加权奖牌总数创建一个虚拟属性。因此,如果他们有 2 枚金币和 1 枚银币,加权总数将为“3.020100”。 1金1银1铜就是“3.010101”

    由于我们要将奖牌数排序为最高,因此列表按 DESC 排序。但是之后我们想要按字母顺序(即 ASC)进行子排序。所以我创建了一个函数,可以对一个单词进行 alpha 反转(即“canada”=>“xzmzwz”)

    将加权总数转换为字符串,连接反向名称(即“3010101xzmzwz”),然后降序排序。瞧。

到目前为止,有人已经弄清楚了如何用大约 2 行代码来做同样的事情。愿意开导我吗?

【问题讨论】:

【参考方案1】:
countries.sort_by do |country|
  medals = country.gold + country.silver + country.bronze
  [-medals, -country.gold, -country.silver, country.name]
end

【讨论】:

这是特定于某个 Ruby 版本的吗?它似乎对我不起作用。 不应该。它在 1.8.7 和 1.9 上适用于我,而且我看不出它不应该在 1.8.6 上运行的任何理由。 sort_by 肯定存在于 1.8.6 中,Array#<=> 也是如此。 请注意,sort_by 不会就地排序。【参考方案2】:

一个简单的方法是将 sort_by 与一些任意格式的字符串一起使用,例如:

countries.sort_by do |c|
  "%010d-%010d-%010d-%s" % [ c.gold, c.silver, c.bronze, c.name ]
end

这会将所有国家/地区转换为 ASCII 可排序列表,方法是将赢得的奖牌数量填充到可能令人发指的 10 位。如果有人赢得超过 100 亿枚奖牌,您的程序可能会出现故障,但这似乎是一个合理的限制。

【讨论】:

+1 表示“合理的约束” :-) 但是,请注意,由于完全无法控制的情况,合理的约束有时会变得不合理:Blog.BusinessOfSoftware.Org/2009/01/… 只有在津巴布韦,您才需要 Bignum 来代表您的银行账户余额。 我不相信这能解决我最初的要求——奖牌数应该按降序排序(最大的在前),但字母顺序的子排序应该是升序的(最小的,或.. z)。因此,按“---”排序将首先排序最少的奖牌。首先是最大奖牌,然后是具有相同编号的国家的字母子排序。奖牌。 可以通过反转数字计数轻松地翻转它,但与早期的解决方案相比,这进入了深入的黑客领域。 "%010d-%010d-%010d-%s" % [ 10_000_000_000 - c.gold, 10_000_000_000 - c.silver, 10_000_000_000 - c.bronze, c.name ]【参考方案3】:

在 Java 中,您可以在对象上实现可比较,然后可以轻松地将其排序到 ArrayList 或 Array 中。 Ruby 中是否有一种机制可以告诉您如何比较两个“国家”对象?

【讨论】:

以上是关于按数字(最高优先)然后按字母(字母顺序)对对象集合进行排序的主要内容,如果未能解决你的问题,请参考以下文章

Pandas str 按字母顺序然后按数字

按字母顺序获取对象的java集合

sql server 按字母顺序排序,然后是数字

除数字外,如何按字母顺序对对象数组进行排序?

按首字母 Javascript 按字母顺序对对象进行排序和分组

用单词和数字按字母顺序排列字符串