2009-06-02 14 views
8

mam ponad tysiąc folderów, każdy folder zawiera jeden lub więcej plików z następującymi nazwami:klienta LINQ zamawiania

punktorowana:

 
Alison.ext 
Heather.ext 
Molly.ext 
Paula.ext 
Sam.ext 

Zleceniodawca:

 
Molly.ext 
Sam.ext 
Heather.ext 
Alison.ext 
Paula.ext 

chciałbym napisać wyrażenie, aby posortować listę zgodnie z opisem powyżej.

Odpowiedz

14
//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]]); 

Zamiast wywoływać orderDict [element [0]] można mieć piękny metody pomocnika, który dba o przypadkach skrajnych (nie istnieje listów, null, a więc o n). Ale taki jest pomysł.

+0

@Yann Schwartz: To były tylko mock nazwy plików, klucz alfabetycznym chcę używać jest pierwszą literą pliku. Dzięki! – Chris

+0

Przepraszamy. Myślałem, że chcesz niestandardowej kolejności alfabetycznej (widziałem dziwniejsze rzeczy :-)) –

+0

EUH, że nie jest to, czego chce? Myślałem, że chciał dobrze .. –

0

Nie wspominając już dokładnie, jakiego rodzaju obiektów, które mają się na liście, ale powiedzmy, że to jakiś rodzajowy układ tak:

public class File { 
    public string FileName { ... } 
    public long FileSize { ... } 
    /* elided */ 
} 

Następnie podano IEnumerable nazywa, powiedzmy, files, można po prostu zrobić:

var result = files.OrderBy(f => f.FileName); 
1
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(); 
} 

wypróbowane i jestem pewien, że są szybsze sposoby, ale przynajmniej jest to z LINQ rzeczy jak pytasz :-)

edit: Właśnie ten zmienił swojego posta i teraz nie mam już jakiś pomysł, co naprawdę chcesz robić, więc mój kod jest prawdopodobnie bezużyteczne dla ciebie ..

+0

Intencją tutaj jest dźwięk.Jest to wątpliwa wydajność, aby wyliczyć kolekcję raz na klucz zamówienia. Ponadto, przerażające jest rozważenie odroczonej realizacji Linq i interakcji Concata i Except. topFiles.Concat (files.Except (topFiles)) –

6

Oto metoda, która daje klucze do zamawiania

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; 
} 

Oto jak to nazwać:

List<File> ordered = Files.OrderBy(f => OrderKey(f.FileName)).ToList(); 
+0

Thx, działało idealnie. Musiał zamówić kody ciągów (zmodyfikowane wizualnie, aby używać ciągów nie char). Musiał sortować w rankingu, a nie alfa. A nawet łapie kody, których nie ma na liście, umieszczając je na końcu. –

0

można przechowywać listę zamówień pożądany w tablicy

int[] iIndex = {3,2,0,4, 1}; 

Say str posiada swoją nieuporządkowaną Lista

List<string> str = new List<string>(); 
str.Add("Alison.ext"); 
str.Add("Heather.ext"); 
. 
. 
. 

Dodaj swoją listę i odpowiadający zamówić w 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 Zamówienie yuor lista dostać yuor spodziewać lista

var result = from ls in dt.AsEnumerable() 
         orderby ls.Field<int>("Order") 
         select ls;  
Powiązane problemy