问题
I have over a thousand folders, each folder contains one or more files with the following names:
Unordered:
Alison.ext Heather.ext Molly.ext Paula.ext Sam.ext
Ordered:
Molly.ext Sam.ext Heather.ext Alison.ext Paula.ext
I would like to write an expression to sort this list as described above.
回答1:
//Creating a dictionary with the custom order
var order = "MSHAP";
var orderDict = order.Select((c,i)=>new {Letter=c, Order=i})
.ToDictionary(o => o.Letter, o => o.Order);
var list = new List<string>{"A.ext", "H.ext", "M.ext", "P.ext", "S.ext"};
//Ordering by the custom criteria
var result = list.OrderBy(item => orderDict[item[0]]);
Instead of calling orderDict[item[0]] you could have a nice helper method that cares for the fringe cases (non existent letters, null, and so on). But that's the idea.
回答2:
Here's a method that produces keys for ordering
public int OrderKey(string fileName)
{
char first = fileName[0];
int result =
first == 'M' ? 1 :
first == 'S' ? 2 :
first == 'H' ? 3 :
first == 'A' ? 4 :
first == 'P' ? 5 :
6;
return result;
}
Here's how to call it:
List<File> ordered = Files.OrderBy(f => OrderKey(f.FileName)).ToList();
回答3:
List<char> sortKeys = new List<char> { 'M', 'S', 'H', 'A', 'P' };
sortKeys.Reverse();
List<FileInfo> files = new List<FileInfo>(6);
foreach(char sortKey in sortKeys)
{
var topFiles = files.Where(file => file.Name.StartsWith(sortKey.ToString()));
var remainingFiles = files.Except(topFiles);
files = topFiles.Concat(remainingFiles).ToList();
}
Untested and I'm sure there are faster ways, but at least it's with linq stuff as you asked :-)
edit: I just saw the edit on your post and now I don't have any idea anymore what you really want to do, so my code is probably useless to you..
回答4:
You didn't mention exactly what sort of objects you have in the list, but let's say it's some generic arrangement like so:
public class File {
public string FileName { ... }
public long FileSize { ... }
/* elided */
}
Then, given an IEnumerable called, say, files
, you can just do:
var result = files.OrderBy(f => f.FileName);
回答5:
You can store the desired order list in an array
int[] iIndex = {3,2,0,4, 1};
Say str holds your unordered List
List<string> str = new List<string>();
str.Add("Alison.ext");
str.Add("Heather.ext");
.
.
.
Add your list and corresponding order into a datatable
DataTable dt = new DataTable();
dt.Columns.Add("Order", typeof(Int32));
dt.Columns.Add("Name");
for (int iCount =0; iCount< str.Count ; iCount ++)
{
DataRow drow1 = dt.NewRow();
drow1[0] = iIndex[iCount];
drow1[1] = str[iCount];
dt.Rows.Add(drow1);
}
dt.AcceptChanges();
Fynally Order yuor list to get yuor expected list
var result = from ls in dt.AsEnumerable()
orderby ls.Field<int>("Order")
select ls;
来源:https://stackoverflow.com/questions/942039/custom-linq-ordering