我有以下数字数组:
Dim lst() As Integer = {4, 3, 200, 250, 670, 1, 450, 3, 10, 15, 900, 450}
我需要将它们作为一系列对象列出,其中包含数字和它们对应的100分排名,结果如下:
Number Rank
900 100
670 90
450 80
450 80
250 60
200 50
15 40
10 30
4 20
3 10
3 10
1 0
我被难住了——我现在得到了这个:
Dim t = From l In lst
Order By l Descending
Select New With {
.Number = l,
.Rank = ((From o In lst Where o > l Select o).Distinct.Count + 1)}
这项技术将用于大约3000多个对象的一系列列表,我怀疑我的方法的性能将是可怕的,当我在完整的数据集上使用它时可以得到改进。
您的解决方案不是最优的,因为当您在匿名对象中设置Rank属性时,您正在枚举每个项目的列表。
一个更聪明的解决方案是利用排序来计算基于最后一个项目索引的percentile
。
var sorted = lst.OrderByDescending(n => n).ToList();
var result = sorted.Select((val) => new
{
Number = val,
Rank = (sorted.Count - (sorted.LastIndexOf(val) + 1)) * 100 / sorted.Count
}).ToList();
这比10倍的解决方案快3000项。
您可以轻松地将我的c#代码转换为VB.NET。
修复…我已经很接近了:
Dim lst() As Integer = {4, 3, 200, 250, 670, 1, 450, 15, 15, 15, 900, 450}
Dim t = (From l In lst Order By l Descending).Select(
Function(l, Index) New With {
.Number = l,
.Rank = 100 - (((From o In lst Where o > l Select o).Count + 1) - 1) * 100 / lst.Count})