タイトルの通り、Sorted Setsで取ってきたランキングで、同一のスコアの場合は順位をランダムにしたい。
# こんなデータがあったとして
ids_and_scores = [[10010818, 155.0],[10026928, 150.0],[10025650, 150.0],[10023988, 150.0],[10023708, 150.0],[10023820, 115.0],[10025925, 110.0],[10024209, 110.0]]
# ここと
[10026928, 150.0],[10025650, 150.0],[10023988, 150.0],[10023708, 150.0]
# ここの順番をランダムにしたい
[10025925, 110.0],[10024209, 110.0]
まずは重複しているスコアを取ってくる。
duplicate_scores = ids_and_scores.group_by { |id_score| id_score[1] }.select { |score, ary| 1 < ary.size }.keys
# => [150.0, 110.0]
重複しているスコアの場合は配列にまとめる。
last_score = 0
id_ary_tmp = ids_and_scores.inject([]) do |output, id_score|
if duplicate_scores.include?(id_score[1])
if output.last.class == Array && last_score == id_score[1]
output.last << id_score[0]
else
output << [id_score[0]]
end
else
output << id_score[0]
end
last_score = id_score[1]
output
end
# => [10010818, [10026928, 10025650, 10023988, 10023708], 10023820, [10025925, 10024209]]
重複しているスコアの配列をシャッフルしてflatten
で配列を作り直す。
id_ary = id_ary_tmp.map do |id_ids|
if id_ids.class == Array
id_ids.shuffle
else
id_ids
end
end.flatten
# => [10010818, 10023988, 10025650, 10026928, 10023708, 10023820, 10024209, 10025925]
メソッドにまとめる。
# 同スコアの場合はランダムで順位づけしたい
def sort_id_considering_duplicate_scores(ids_and_scores)
duplicate_scores = ids_and_scores.group_by { |id_score| id_score[1] }.select { |score, ary| 1 < ary.size }.keys
last_score = 0
id_ary_tmp = ids_and_scores.inject([]) do |output, id_score|
if duplicate_scores.include?(id_score[1])
if output.last.class == Array && last_score == id_score[1]
output.last << id_score[0]
else
output << [id_score[0]]
end
else
output << id_score[0]
end
last_score = id_score[1]
output
end
id_ary = id_ary_tmp.map do |id_ids|
if id_ids.class == Array
id_ids.shuffle
else
id_ids
end
end
id_ary.flatten
end
一応動いているっぽいけどもっとシンプルにできそう。。。
sort_id_considering_duplicate_scores(ids_and_scores)
# => [10010818, 10026928, 10023988, 10023708, 10025650, 10023820, 10024209, 10025925]
sort_id_considering_duplicate_scores(ids_and_scores)
# => [10010818, 10026928, 10023988, 10025650, 10023708, 10023820, 10024209, 10025925]
sort_id_considering_duplicate_scores(ids_and_scores)
# => [10010818, 10023708, 10025650, 10023988, 10026928, 10023820, 10024209, 10025925]
sort_id_considering_duplicate_scores(ids_and_scores)
# => [10010818, 10023988, 10025650, 10023708, 10026928, 10023820, 10024209, 10025925]
sort_id_considering_duplicate_scores(ids_and_scores)
# => [10010818, 10025650, 10023708, 10023988, 10026928, 10023820, 10025925, 10024209]
※バグがあったので一部修正。