Ruby Natural Sort / Order

时间:2013-01-11 05:02:59

标签: ruby ruby-on-rails-3 sorting ruby-on-rails-3.2

我正在使用Challonge API,在查询锦标赛时,每个匹配都返回一个indentifier=即A-Z。在前26个匹配后,标识符变为AA-AZ,然后BA-BZ等,

当拉出单个锦标赛的整个比赛列表并尝试在标识符上使用.sort_by时,结果按以下顺序排列:

A AA AB AC ... B BA BB BC ... C ...

为了正确显示匹配,他们需要按此顺序:

A B C ... AA AB AC ... BA BB BC ...

我花了一些时间搜索,找不到任何真正简单的方法来实现这一目标。我发现的大多数帖子都涉及文件名或编号,我不确定如何将其应用于这种情况。

非常感谢任何帮助!

修改

这是一个示例回复:

[{"match":{"created_at":"2013-01-09T23:25:22-05:00","has_attachment":false,"id":8148294,"identifier":"CK","loser_id":null,"player1_id":null,"player1_is_prereq_match_loser":true,"player1_prereq_match_id":8148251,"player1_votes":null,"player2_id":null,"player2_is_prereq_match_loser":false,"player2_prereq_match_id":8148293,"player2_votes":null,"round":-9,"started_at":null,"state":"pending","tournament_id":320424,"updated_at":"2013-01-09T23:25:25-05:00","winner_id":null,"prerequisite_match_ids_csv":"8148251,8148293","scores_csv":""}}

您可以在那里看到"indentifier":"CK"。使用.length时,我不断获得undefined method 'length'。在控制器中我使用@tournamentlist = tournamentlist.matches.sort...

2 个答案:

答案 0 :(得分:8)

或者只是:

ids = ["AA", "A", "C", "CA", "CCC"]
ids.sort { |a,b| [a.length, a] <=> [b.length, b] }
#=> ["A", "C", "AA", "CA", "CCC"]

或者,使用sort_by,甚至更短:

ids.sort_by { |a| [a.length, a] }

参考:How can I sort by multiple conditions with different orders?

答案 1 :(得分:3)

这很简单,只需将该数组分组,其中每个组包含相同长度的ID(单字母ID,双字母ID等),单独排序然后合并。

ids = %w[A B C AA AB AC BA BB BC AAB BBC CBA].shuffle
ids # => ["CBA", "BA", "C", "BC", "BB", "AC", "BBC", "AAB", "AA", "B", "AB", "A"]

sorted_ids = ids.group_by(&:length).sort{|(len1, _), (len2, _)| len1 <=> len2 }.map do |_, id_group|
  id_group.sort
end.flatten

sorted_ids # => ["A", "B", "C", "AA", "AB", "AC", "BA", "BB", "BC", "AAB", "BBC", "CBA"]

让我们打破这段代码:

.group_by(&:length)

这将处理原始数组和组字符串的长度,产生一个数组,其中每个元素也是两个元素的数组:第一个元素是长度,第二个元素是这个长度的字符串数组。

.sort{|(len1, _), (len2, _)| len1 <=> len2 }

这部分对id组进行排序,使它们按照递增的长度顺序出现(所有单字母字符串首先出现)。

.map {|_, id_group| id_group.sort }

它将占用所有(length, strings)对,对字符串进行排序并返回。该调用产生数组数组。

.flatten

flatten执行它所说的:取嵌套数组并“展平”它,这样就没有嵌套。

相关问题