【问题标题】:Sort a List based on a Pre-Sorted List根据预先排序的列表对列表进行排序
【发布时间】:2015-01-08 15:39:34
【问题描述】:

如何根据预先排序的列表对列表进行排序。

我有一个已经排序的列表。说,我的排序列表是

{"Junior Developer", "Developer", "Senior Developer", "Project Lead"}

现在,我想按照与上述列表相同的顺序对上述列表的任何子集进行排序。也就是说,如果我有输入

{"Developer", "Junior Developer"},我希望输出为{"Junior Developer", "Developer"}

如果输入是{"Project Lead", "Junior Developer", "Developer"},我希望输出为

{"Junior Developer", "Developer", "Project Lead"}. 

我怎样才能达到同样的效果?

【问题讨论】:

  • .IndexOf()排序
  • 只是为了扩展@zerkms 评论:input.OrderBy(x => bigSortedList.IndexOf(x))
  • 也许不是格式最好的问题,但仍然是一个合法的问题。为什么投反对票?
  • @cost 我想知道同样的问题,但赞成票似乎已经自动处理了。关于格式,如果有人对其进行编辑以符合标准并从中学习,我将非常高兴。谢谢!

标签: c# list sorting


【解决方案1】:

最简单的方法是使用 LINQ 的 .OrderBy 扩展方法以及预排序集合的 IndexOf 方法(或等效方法)。这里的想法是使用不同的值作为“排序键”进行排序(这非常有用,因为我们经常希望根据对象的属性之一对对象进行排序)。

var sorted = listToSort.OrderBy(s => listPreSorted.IndexOf(s)).ToList();

下面是一个数组示例:http://ideone.com/7oshhZ


请注意,如果您的列表非常很大,这可能会很慢,因为您的目标列表中的每个项目都必须在您的预排序集合中按顺序查找(O(N * M),其中N 是目标列表的长度,M 是预排序列表的长度。

要克服这个限制,您可以生成一个查找,将您的预排序列表中的项目映射到它们的索引,然后在您的 .OrderBy 中使用此查找(这将具有 O(N + M) 的运行时,您可以重新- 如果需要,使用查找):

var preSortedLookup =
        listPreSorted.Select((v, i) => new { Key = v, Value = i })
                     .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

var sorted = listToSort.OrderBy(s => preSortedLookup[s]).ToList();

【讨论】:

    【解决方案2】:

    如果两个列表中的任何一个没有重复项,那么您可以简单地使用Intersect,这将保留顺序:

    var allRoles = new[] {"Junior Developer", "Developer",
                          "Senior Developer", "Project Lead"};
    var roles = new[] {"Developer", "Junior Developer"};
    var sortedRoles = allRoles.Intersect(roles);
    

    这可能比按IndexOf 排序更有效,但除非列表很长,否则您不太可能注意到差异。

    【讨论】:

    • @Mathew:不知道 Intersect 保留了订单。谢谢!
    【解决方案3】:

    假设您有一个排序列表 listA,而您将拥有的另一个列表是 listB。 每次从 listB 读取时,检查元素是否在 listA 中,并根据该顺序列出您的列表。

    【讨论】:

      【解决方案4】:

      如果负载很大,试试字典?

      1,

      dictionary<string,int>
      

      使用这个字典来存储字符串和索引

      2, 生成一个list&lt;string&gt; result 将长度设置为您的带有虚拟数据的字符串数

      3 然后找到正确的索引号 按索引将字符串写入result

      【讨论】:

        猜你喜欢
        • 2023-04-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-05
        • 2022-01-02
        相关资源
        最近更新 更多