我有一个通用列表
简化示例
var list = new List<string>()
{
"lorem1.doc",
"lorem2.docx",
"lorem3.ppt",
"lorem4.pptx",
"lorem5.doc",
"lorem6.doc",
};
我想要做的是根据外部列表排序
对这些项目进行排序在示例中
var sortList = new[] { "pptx", "ppt", "docx", "doc" };
// Or
var sortList = new List<string>() { "pptx", "ppt", "docx", "doc" };
linq内置了什么东西可以帮助我实现这个目标,还是我必须采用foreach方式?
答案 0 :(得分:8)
使用此列表,您可以IndexOf
使用Enumerable.OrderBy
:
var sorted = list.OrderBy(s => sortList.IndexOf(Path.GetExtension(s)));
因此sortList
中的扩展名索引确定了另一个列表中的优先级。未知扩展名具有最高优先级,因为它们的索引为-1。
但是您需要在扩展中添加一个点才能使其正常工作:
var sortList = new List<string>() { ".pptx", ".ppt", ".docx", ".doc" };
如果这不是一个选项,你必须摆弄Substring
或Remove
,例如:
var sorted = list.OrderBy(s => sortList.IndexOf(Path.GetExtension(s).Remove(0,1)));
答案 1 :(得分:6)
即使某些文件名没有扩展名,此解决方案仍然有效:
var sortList = new List<string>() { "pptx", "ppt", "docx", "doc" };
var list = new List<string>()
{
"lorem1.doc",
"lorem2.docx",
"lorem3.ppt",
"lorem4.pptx",
"lorem5.doc",
"lorem6.doc",
};
var result =
list.OrderBy(f => sortList.IndexOf(Path.GetExtension(f).Replace(".","")));
答案 2 :(得分:1)
您可以尝试使用Array.IndexOf()方法:
var sortedList = list.OrderBy(i => sortList.IndexOf(System.IO.Path.GetExtension(i))).ToList();
答案 3 :(得分:1)
sortDicionary
效率更高:
var sortDictionary = new Dictionary<string, int> {
{ ".pptx", 0 },
{ ".ppt" , 1 },
{ ".docx", 2 },
{ ".doc" , 3 } };
var sortedList = list.OrderBy(i => {
var s = Path.GetExtension(i);
int rank;
if (sortDictionary.TryGetValue(s, out rank))
return rank;
return int.MaxValue; // for unknown at end, or -1 for at start
});
这种查询方式为O(1)
而不是O(# of extensions)
。
此外,如果您有大量文件名和少量扩展名,那么实际上可能会更快
var sortedList = list
.GroupBy(p => Path.GetExtension(p))
.OrderBy(g => {
int rank;
if (sortDictionary.TryGetValue(g.Key, out rank))
return rank;
return int.MaxValue; // for unknown at end, or -1 for at start
})
.SelectMany(g => g);
这意味着排序按输入中不同扩展的数量而不是输入中的项目数量进行缩放。
这也允许您为两个扩展提供相同的优先级。
答案 4 :(得分:0)
这是另一种不使用OrderBy
的方式:
var res =
sortList.SelectMany(x => list.Where(f => Path.GetExtension(f).EndsWith(x)));
请注意,此方法的复杂性为O(n * m)
n = sortList.Count
和m list.Count
。
OrderBy
方法最坏情况的复杂性是O(n * m * log m)
,但通常它会更快(因为IndexOf
不会始终在O(n)
中)。但是,对于小n
和m
,您不会发现任何差异。
对于大型列表,最快的方式(复杂性O(n+m)
)可以构建临时查找,即:
var lookup = list.ToLookup(x => Path.GetExtension(x).Remove(0,1));
var res = sortList.Where(x => lookup.Contains(x)).SelectMany(x => lookup[x]);