如何使用C#获取列表中多个数字的排名列表?
how to get the rank list of multiple number in a list using C#?
我在 C# 中有以下列表:
List<double> arr = new List<double> { 5, 10, 7, 15, 9, 21, 1 };
我想将他们的排名存储在另一个列表中,例如 List<double> rank
。最后我想得到以下内容:
6 3 5 2 4 1 7
我该怎么做?
如果all arr中的项目是distinct,你可以创建一个dictionary :
List<double> arr = new List<double> { 5, 10, 7, 15, 9, 21, 1 };
var ranks = arr
.OrderByDescending(item => item)
.Select((item, index) => new {
item = item,
rank = index + 1,
})
.ToDictionary(x => x.item, x => x.rank);
然后使用ranks
找出对应等级的项目:
int rankOf5 = ranks[5]; // 6
测试
string test = string.Join(" ", arr.Select(x => ranks[x]));
// 6 3 5 2 4 1 7
Console.Write(test);
编辑:用循环测试:
foreach (var item in arr)
Console.Write(ranks[item]);
或
for (int i = 0; i < arr.Count; ++i)
Console.Write(ranks[arr[i]]);
编辑 2 如果 arr
可以 有重复项,例如
// 21 appears 2 times
List<double> arr = new List<double> { 5, 10, 7, 15, 9, 21, 21, 1 };
您可能想要计算所谓的 密集排名
var ranks = arr
.GroupBy(item => item)
.OrderByDescending(chunk => chunk.Key)
.Select((chunk, index) => new {
item = chunk.Key,
rank = index + 1
})
.ToDictionary(x => x.item, x => x.rank);
string test = string.Join(" ", arr.Select(x => ranks[x]));
// 6 3 5 2 4 1 1 7
Console.Write(test);
可能最短的方法是在排序列表后使用 IndexOf
:
List<double> arr = new List<double> { 5, 10, 7, 15, 9, 21, 1 };
var ranking = arr.OrderByDescending(item => item)
.Select(item => arr.IndexOf(item)+1)
.ToList();
//Output: 6, 2, 5, 2, 4, 1, 7
或者只是玩 OrderBy
和 Select
:
var ranking = arr.Select((item, index) => new { Item = item, Index = index })
.OrderByDescending(item => item.Item)
.Select((item, index) => new { Item = item.Item, OriginalIndex = item.Index, Rank = ++index })
.OrderBy(item => item.OriginalIndex)
.Select(item => item.Rank)
.ToList();
//Output: 6, 2, 5, 2, 4, 1, 7
List<double> arr = new List<double> { 5, 10, 7, 15, 9, 21, 1 };
var rankDict = arr.Distinct().OrderByDescending(num=>num)
.Select((number, index) => new {Number = number, Rank = index})
.ToDictionary(m => m.Number, m => m.Rank);
var rankedArray = new List<double>();
foreach(var num in arr)
{
rankedArray.Add(rankDict[num] + 1);
}
Console.WriteLine(string.Join("-", rankedArray));
Fiddle - https://dotnetfiddle.net/7C5o52
我在 C# 中有以下列表:
List<double> arr = new List<double> { 5, 10, 7, 15, 9, 21, 1 };
我想将他们的排名存储在另一个列表中,例如 List<double> rank
。最后我想得到以下内容:
6 3 5 2 4 1 7
我该怎么做?
如果all arr中的项目是distinct,你可以创建一个dictionary :
List<double> arr = new List<double> { 5, 10, 7, 15, 9, 21, 1 };
var ranks = arr
.OrderByDescending(item => item)
.Select((item, index) => new {
item = item,
rank = index + 1,
})
.ToDictionary(x => x.item, x => x.rank);
然后使用ranks
找出对应等级的项目:
int rankOf5 = ranks[5]; // 6
测试
string test = string.Join(" ", arr.Select(x => ranks[x]));
// 6 3 5 2 4 1 7
Console.Write(test);
编辑:用循环测试:
foreach (var item in arr)
Console.Write(ranks[item]);
或
for (int i = 0; i < arr.Count; ++i)
Console.Write(ranks[arr[i]]);
编辑 2 如果 arr
可以 有重复项,例如
// 21 appears 2 times
List<double> arr = new List<double> { 5, 10, 7, 15, 9, 21, 21, 1 };
您可能想要计算所谓的 密集排名
var ranks = arr
.GroupBy(item => item)
.OrderByDescending(chunk => chunk.Key)
.Select((chunk, index) => new {
item = chunk.Key,
rank = index + 1
})
.ToDictionary(x => x.item, x => x.rank);
string test = string.Join(" ", arr.Select(x => ranks[x]));
// 6 3 5 2 4 1 1 7
Console.Write(test);
可能最短的方法是在排序列表后使用 IndexOf
:
List<double> arr = new List<double> { 5, 10, 7, 15, 9, 21, 1 };
var ranking = arr.OrderByDescending(item => item)
.Select(item => arr.IndexOf(item)+1)
.ToList();
//Output: 6, 2, 5, 2, 4, 1, 7
或者只是玩 OrderBy
和 Select
:
var ranking = arr.Select((item, index) => new { Item = item, Index = index })
.OrderByDescending(item => item.Item)
.Select((item, index) => new { Item = item.Item, OriginalIndex = item.Index, Rank = ++index })
.OrderBy(item => item.OriginalIndex)
.Select(item => item.Rank)
.ToList();
//Output: 6, 2, 5, 2, 4, 1, 7
List<double> arr = new List<double> { 5, 10, 7, 15, 9, 21, 1 };
var rankDict = arr.Distinct().OrderByDescending(num=>num)
.Select((number, index) => new {Number = number, Rank = index})
.ToDictionary(m => m.Number, m => m.Rank);
var rankedArray = new List<double>();
foreach(var num in arr)
{
rankedArray.Add(rankDict[num] + 1);
}
Console.WriteLine(string.Join("-", rankedArray));
Fiddle - https://dotnetfiddle.net/7C5o52