3

我正在使用Challonge API,在查询锦标赛时,每场比赛都会返回一个indentifier=AZ。在前 26 个匹配之后,标识符变为AA-AZthen 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...

4

2 回答 2

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] }

参考:如何按不同订单的多个条件进行排序?

于 2013-01-11T05:17:47.547 回答
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照它说的做:采用嵌套数组并“展平”它,这样就没有嵌套。

于 2013-01-11T05:09:59.430 回答