如何在 C# 中对元素进行排名,尤其是当它有重复项时
How to rank elements in c# especially when it has duplicates
我有一个对数组元素进行排名的需求,并且数组有重复值。我尝试遵循此 Ranking items in a list with LINQ 但是当数组中有重复值时这不起作用。在 c# 中有什么简单的方法可以做到这一点?
例如:
input = [650,150,150,200]
output = [1,3,3,2]
例如:
input = [650,200,200,150]
output = [1,2,2,3]
更新:需求如下,如果我在数组中再增加一个元素呢
例如:[650,150,150,200,100] 输出需要是 [1,3,3,2,5] 而不是 [1,3,3,2,4]
您可以创建一个不同且有序的项目数组,然后使用索引确定每个项目的排名。
var ranks = input.Distinct().OrderByDescending(x => x).ToArray();
var ranked = input.Select(x => Array.IndexOf(ranks, x) + 1);
评论后更新
如果需要跳过排名,只需删除 Distinct
:
var ranks = input.OrderByDescending(x => x).ToArray();
var ranked = input.Select(x => Array.IndexOf(ranks, x) + 1);
Array.IndexOf
有重复时取第一个元素
您可以创建字典作为排名查找源:
int[] array = new[] {650,150,150,200};
Dictionary<int, int> numRanks = array
.GroupBy(i => i)
.OrderByDescending(g => g.Key)
.Select((g, index) => (num:g.Key, rank:index+1))
.ToDictionary(x => x.num, x => x.rank);
int[] result = array.Select(i => numRanks[i]).ToArray();
对于更新后的要求,您可以使用类似的方法 Lookup<TKey, TValue>
:
var rankLookup = array
.OrderByDescending(i => i)
.Select((num, index) => (num, index))
.ToLookup(x => x.num, x => x.index + 1);
int[] result = array.Select(i => rankLookup[i].First()).ToArray();
查找就像一本允许重复键的字典。你需要在这里使用 First
因为你只对排名感兴趣。如果你使用 Count()
你就会知道它有多少重复项。
我有一个对数组元素进行排名的需求,并且数组有重复值。我尝试遵循此 Ranking items in a list with LINQ 但是当数组中有重复值时这不起作用。在 c# 中有什么简单的方法可以做到这一点?
例如:
input = [650,150,150,200]
output = [1,3,3,2]
例如:
input = [650,200,200,150]
output = [1,2,2,3]
更新:需求如下,如果我在数组中再增加一个元素呢 例如:[650,150,150,200,100] 输出需要是 [1,3,3,2,5] 而不是 [1,3,3,2,4]
您可以创建一个不同且有序的项目数组,然后使用索引确定每个项目的排名。
var ranks = input.Distinct().OrderByDescending(x => x).ToArray();
var ranked = input.Select(x => Array.IndexOf(ranks, x) + 1);
评论后更新
如果需要跳过排名,只需删除 Distinct
:
var ranks = input.OrderByDescending(x => x).ToArray();
var ranked = input.Select(x => Array.IndexOf(ranks, x) + 1);
Array.IndexOf
有重复时取第一个元素
您可以创建字典作为排名查找源:
int[] array = new[] {650,150,150,200};
Dictionary<int, int> numRanks = array
.GroupBy(i => i)
.OrderByDescending(g => g.Key)
.Select((g, index) => (num:g.Key, rank:index+1))
.ToDictionary(x => x.num, x => x.rank);
int[] result = array.Select(i => numRanks[i]).ToArray();
对于更新后的要求,您可以使用类似的方法 Lookup<TKey, TValue>
:
var rankLookup = array
.OrderByDescending(i => i)
.Select((num, index) => (num, index))
.ToLookup(x => x.num, x => x.index + 1);
int[] result = array.Select(i => rankLookup[i].First()).ToArray();
查找就像一本允许重复键的字典。你需要在这里使用 First
因为你只对排名感兴趣。如果你使用 Count()
你就会知道它有多少重复项。