在列表C#中记录数字的等级

本文关键字:数字 记录 列表 | 更新日期: 2023-09-27 18:27:17

问题:我有一个列表编号为(List<List<int>> listNumberCollection)的列表:4行x 3列

1 3 9
6 5 6
3 2 7
2 7 2

我如何在列中记录排名(最小的数字是第一),所以它应该是:

1 2 4
4 3 2
3 1 3
2 4 1

我的工作:为了在一列中排序数字,我编写了一个换位函数(4列×3行):

1 6 3 2
3 5 2 7
9 6 7 2
private List<List<Double>> MatrixTransposition(int k, List<List<Double>> listNumberCollection)
{
      var revisedAllRanks = new List<List<Double>>();
      for (int i = 0; i < k; i++ )
      {
           var allRanks = new List<Double>();
           allRanks.AddRange(listNumberCollection.Select(value => value[i]));
           revisedAllRanks.Add(allRanks);
      }
      return revisedAllRanks;
}

我试图创建一个名为NumberRank的类,它有两个属性(Number,Rank),并添加到NumberRank列表中

var revisedListNumberCollection = MatrixTransposition(k, listNumberCollection);
var listNumberRanks = new List<List<NumberRank>>();
foreach(List<Double> vectorsCollection in revisedListNumberCollection)
{                    
     List<NumberRank> numberRanks = vectorsCollection.OrderByDescending(number => number).Select((number, i) => new NumberRank(number, i + 1)).ToList();                        
     listNumberRanks.Add(numberRanks);
}

然而,我得到的结果是有秩的有序数字(第一列:1-1 2-2 3-3 6-4…),而不是我想要的(1-1 6-4 3-3 2-2)谢谢

在列表C#中记录数字的等级

使用纯Linq 可以轻松完成

var input = new List<List<int>>() {
    new List<int> { 1, 6, 3, 2 },
    new List<int> { 3, 5, 2, 7 },
    new List<int> { 9, 6, 7, 2 }
};
var result = input.Select(l =>
        l.Select((x, i) => new { x = x, i = i}) // selecting index
         .OrderBy(z => z.x) // sorting by value
         .Select((z, j) => new { i = z.i, j = j + 1 }) // selecting rank
         .OrderBy(z => z.i) // sorting by initial index
         .Select(z => z.j)  // returning rank
         .ToList()
     ).ToList();
// List<List<int>>(3)
// {
//    List<int>(4) { 1, 4, 3, 2 },
//    List<int>(4) { 2, 3, 1, 4 },
//    List<int>(4) { 4, 2, 3, 1 } 
//}

更新要将行转换为列并返回,您可以执行以下操作:

var transp_input = Enumerable.Range(0, input[0].Count)
                             .Select(i => input.Select(x => x[i]));

然后你计算

var transp_result = transp_input.Select(l =>
        l.Select((x, i) => new { x = x, i = i }) // selecting index
         .OrderBy(z => z.x) // sorting by value
         .Select((z, j) => new { i = z.i, j = j + 1 }) // selecting rank
         .OrderBy(z => z.i) // sorting by initial index
         .Select(z => z.j)  // returning rank
         .ToList()
     ).ToList();

并转置回

var result = Enumerable.Range(0, transp_result[0].Count)
                       .Select(i => transp_result.Select(x => x[i]).ToList()).ToList();

我会选择以下选项:

var input = new List<List<int>>() {
    new List<int> { 1, 6, 3, 2 },
    new List<int> { 3, 5, 2, 7 },
    new List<int> { 9, 6, 7, 2 }
};
var results = new List<List<int>>(input.Count);
foreach (var list in input)
{
    var rankDict = list.OrderBy(x => x).Select((v, i) => new { v, i }).ToDictionary(x => x.v, x => x.i);
    results.Add(list.Select(x => rankDict[x] + 1).ToList());
}
foreach (var list in results)
{
    Console.WriteLine(string.Join(" ", list.Select(x => x.ToString())));
}

这不是纯粹的LINQ,但做你所期望的。结果是:

1 4 3 2
2 3 1 4
4 2 3 1

但是,它有一个限制:它要求单个列表值是唯一的。