2010-02-09 181 views
3

我正在構建一個小工具來顯示奧運獎牌數。我有一個「國家」對象的集合,每個對象都有一個「名稱」屬性,以及「金牌」,「銀牌」,「銅牌」的獎牌數量。按數字排序(最高優先),然後按字母排序(按字母順序排列)

列表應該被排序: 1.總徽章計數首先 2.如果相同獎牌,子排序類型 3(金>銀>青銅,即兩個金> 1個金+ 1銀)。如果相同的獎牌和類型,按字母順序排序

我在做這個紅寶石,但我認爲語言無所謂。我確實找出了一個解決方案,但是如果覺得必須有更加優雅的方式來做到這一點。

這裏就是我所做的:

  1. 創建加權獎牌總數虛擬屬性。所以如果他們有2金1銀,加權總數將是「3.020100」。 1金和1銀和1銅將會是「3.010101」

  2. 既然我們想按照最高的獎牌數排序,那麼排序是DESC。但是之後我們想按字母順序進行分類(即ASC)。所以我創建了一個函數,可以將一個單詞反轉(即「加拿大」=>「xzmzwz」)

  3. 將加權合計轉換爲字符串,concat反相名稱(即「3010101xzmzwz」),然後降序排序。瞧。

到目前爲止,有人已經想出瞭如何在大約2行代碼中做同樣的事情。照顧開導我?

回答

9
countries.sort_by do |country| 
    medals = country.gold + country.silver + country.bronze 
    [-medals, -country.gold, -country.silver, country.name] 
end 
+0

這是特定於某個Ruby版本嗎?它似乎不適合我。 – Beanish 2010-02-09 21:33:45

+0

它不應該。它適用於1.8.7和1.9,我沒有看到爲什麼它不適用於1.8.6。 'sort_by'絕對存在於1.8.6中,'Array#<=>'也是如此。 – sepp2k 2010-02-09 21:36:57

+0

請注意,'sort_by'不就地排序。 – sepp2k 2010-02-09 21:37:46

1

一個簡單的方法是用一些任意格式的字符串sort_by使用,如:

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

這通過填充獎牌數贏得了大概所有國家轉換到一個ASCII排序列表離譜的10個地方。如果有人獲得了超過100億的獎牌,你的程序可能會出現故障,但這似乎是一個合理的限制。

+0

對於「合理約束」:-)但是,請注意,由於情況完全不受控制,合理的約束有時會變得不合理:http://Blog.BusinessOfSoftware.Org/2009/01/bos- digest --- when-good-assumptions-go-bad.html – 2010-02-09 23:00:16

+0

只有在津巴布韋,你需要一個Bignum來代表你的銀行賬戶餘額。 – tadman 2010-02-10 00:58:13

+0

我不相信這解決了我原來的一個要求 - 獎牌數應該按降序排列(最大的第一個),但按字母排序的子排序應該是升序(最小或a..z)。 因此,按「---」排序將首先排序最小數量的獎牌。首先是最大的獎牌,然後是按照字母順序排序的國家。的獎牌。 – dlehman 2010-02-10 01:16:02

0

在Java中,您可以在您的對象上實現可比較的功能,然後它可以很容易地在ArrayList或Array中排序。 Ruby中是否有一種機制來告訴如何比較兩個「國家」對象?