如何根据预先排序的列表对列表进行排序。
我有一个已经排序的列表。比如,我的排序列表是
{"Junior Developer", "Developer", "Senior Developer", "Project Lead"}
现在,我想按照与上面列表相同的顺序对上面列表的任何子集进行排序。也就是说,如果我有输入
{"Developer", "Junior Developer"}
,我希望输出为{"Junior Developer", "Developer"}
如果输入为{"Project Lead", "Junior Developer", "Developer"}
,我希望输出为
{"Junior Developer", "Developer", "Project Lead"}.
我怎样才能达到同样的目标?
答案 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