基于预排序列表对列表进行排序

时间:2014-11-11 22:36:42

标签: c# list sorting

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

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

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

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

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

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

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

我怎样才能达到同样的目标?

4 个答案:

答案 0 :(得分:10)

最简单的方法是使用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();

答案 1 :(得分:1)

如果两个列表中的任何一个都有没有重复,那么您只需使用Intersect即可保留订单:

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

如果你负担很重,试试一本字典?

1,

dictionary<string,int>

使用此字典存储字符串和索引

2, 生成list<string> result设置长度作为带有虚拟数据的字符串数

3 然后找到正确的索引号 通过索引

将字符串写入result