使用List.OrderBy按存储在另一个列表中的位置对列表进行排序

时间:2018-06-11 15:26:00

标签: c# list sorting

我有两个列表,一个是位置变量(和其他东西,但这是其中的重要部分),另一个列出了我需要排序的元素。是否可以使用OrderBy在第一个列表中按位置变量对第二个列表进行排序?

我可以正常排序,但我对OrderBy的运作很好奇,所以我想尝试一下。

谢谢!

2 个答案:

答案 0 :(得分:2)

正确的方法是将两个列表压缩连接在一起 - zip join是一个连接,它将两个序列放在一起,就像拉链的两半一样,因此得名。假设您有一个分数列表和一个播放器列表,scores[i]对应players[i]所有i,并且您希望按分数对玩家进行排序:< / p>

List<int> scores = whatever;
List<Player> players = whatever;
List<Player> sortedPlayers = players
  .Zip(scores, (player, score) => new { player, score })
  .OrderBy(pair => pair.score)
  .Select(pair => pair.player)
  .ToList();

按照每个步骤进行操作。

  • zip连接使用匿名类型生成一系列(玩家,分数)对。 (在C#7中你应该使用元组代替:练习:这样做。)
  • 我们按分数对对象列表进行排序
  • 我们从排序的对序列中提取玩家
  • 我们将已排序的玩家序列转换为列表

我们已经完成了。

替代解决方案:上述解决方案适用于任何对应的序列对。如果序列是索引,那么我们可以使用这个替代解决方案:

List<int> scores = whatever;
List<Player> players = whatever;
List<Player> sortedPlayers = players
  .Select((player, index) => new { player, index })
  .OrderBy(pair => scores[pair.index])
  .Select(pair => pair.player)
  .ToList();

再次,请继续:

  • 我们从一系列球员开始
  • 我们生成一系列(玩家,指数)对,所以现在我们知道每个玩家在其列表中的位置,从而知道得分列表。 (再次:在C#7中使用元组。)
  • 我们使用索引对分数进行排序
  • 我们从对中提取球员
  • 我们把它变成一个列表。

答案 1 :(得分:-1)

如果我理解你,你可以做以下事情:

IEnumerator<int> position = listWithPositions.GetEnumerator();
var sortedList = listToSort.OrderBy(p => 
    {
        position.MoveNext();
        return position.Current;
    }
).ToList<Object>();

修改:我需要补充一点,这不是一种好习惯,您可能需要考虑在SortedDictionary中组织数据。