我在Ruby中有以下数字数组(越高越好),我想对它们进行排名.换句话说,我想转换以下排序列表:
[89 52 52 36 18 18 5]
Run Code Online (Sandbox Code Playgroud)
到以下职级:
[1 2 2 4 5 5 7]
Run Code Online (Sandbox Code Playgroud)
例如,获胜者获得第一名,第二名获得并列,依此类推.显然,重要的一点是,关系是可能的,那些关系必须跳过相应的级别.任何数量的关系都是可能的(3人分享第二名).
有没有一种优雅的方式来执行这种操作?
fal*_*tru 11
a = [89, 52, 52, 36, 18, 18, 5]
rank = 1
a.group_by {|x| x}.map { |k,v|
ret = [rank] * v.size
rank += v.size
ret
}.flatten
# => [1, 2, 2, 4, 5, 5, 7]
Run Code Online (Sandbox Code Playgroud)
UPDATE
rank, i = 1, 0
a.map { |x|
i += 1
x != a[i-2] ? rank = i : rank
}
# => [1, 2, 2, 4, 5, 5, 7]
Run Code Online (Sandbox Code Playgroud)
使用Enumerable#each_with_index以避免通过数组的每个迭代去:
a = [89, 52, 52, 36, 18, 18, 5]
rank = 1
a.each_with_index.map{|value, i| a[i-1] == value ? rank : rank = i+1}
Run Code Online (Sandbox Code Playgroud)
编辑:我想我也应该测试我的,这里是结果
Calculating -------------------------------------
falsetru 344 i/100ms
sawa 436 i/100ms
Jordan 1174 i/100ms
Iceman 46 i/100ms
simongarnier 710 i/100ms
-------------------------------------------------
falsetru 3411.0 (±3.7%) i/s - 17200 in 5.049500s
sawa 4437.4 (±3.4%) i/s - 22236 in 5.017073s
Jordan 11746.5 (±2.3%) i/s - 59874 in 5.099797s
Iceman 463.4 (±2.4%) i/s - 2346 in 5.065717s
simongarnier 7442.1 (±3.2%) i/s - 37630 in 5.061725s
Run Code Online (Sandbox Code Playgroud)
不是最好的,但还是打得很好!
a = [89, 52, 52, 36, 18, 18, 5]
a.map{ |e| a.index(e) + 1 }
# => [1, 2, 2, 4, 5, 5, 7]
Run Code Online (Sandbox Code Playgroud)
编辑:
来自@Jordan gist的基准(https://gist.github.com/jrunning/488de3a19428b9ebb488)
Calculating -------------------------------------
falsetru 419 i/100ms
sawa 514 i/100ms
Jordan 1438 i/100ms
Iceman 57 i/100ms
-------------------------------------------------
falsetru 4232.8 (±2.5%) i/s - 21369 in 5.051639s
sawa 5032.0 (±3.5%) i/s - 25186 in 5.011681s
Jordan 15057.5 (±2.7%) i/s - 76214 in 5.065319s
Iceman 575.7 (±1.9%) i/s - 2907 in 5.051481s
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1040 次 |
| 最近记录: |