如何使用C#获得列表中多个数字的排名列表

本文关键字:列表 数字 何使用 | 更新日期: 2023-09-27 18:03:01

我在C#中有以下列表:

List<double> arr = new List<double> { 5, 10, 7, 15, 9, 21, 1 };

我想将他们的排名存储在另一个列表中,例如List<double> rank。最后我想要得到以下:

6 3 5 2 4 1 7

我该怎么做?

如何使用C#获得列表中多个数字的排名列表

如果arr中的所有项都是不同的,则可以创建字典

  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]]); 

如果arr可以具有重复项,则编辑2,例如

// 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

或者只是玩OrderBySelect:

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