2009-06-02 11 views
8

He más de mil carpetas, cada carpeta contiene uno o más archivos con los siguientes nombres:personalizada LINQ pedidos

desordenada:

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

Z:

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

me gustaría escribir una expresión para ordenar esta lista como se describe arriba.

Respuesta

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

en lugar de llamar orderDict [elemento [0]] usted podría tener un método de ayuda agradable que cuida de los casos marginales (letras inexistente, nulo, y así o norte). Pero esa es la idea.

+0

@Yann Schwartz: Esos eran sólo nombres de archivo simulacros, la clave alfabética quiero usar es la primera letra del archivo. ¡Gracias! – Chris

+0

Lo siento. Pensé que querías un orden alfabético personalizado (he visto cosas más extrañas :-)) –

+0

euh que no es lo que él quiere? Pensé que él también quería eso .. –

0

usted no mencionó exactamente qué tipo de objetos que tiene en la lista, pero digamos que es un arreglo genérica de este modo:

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

Entonces, dado un IEnumerable llamada, por ejemplo, files, puede acaba de hacer:

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

No probado y estoy seguro de que hay formas más rápidas, pero al menos es LINQ con cosas como lo pidió :-)

edición: que acaba de ver la edición de su poste y ahora no tengo la menor idea más de lo que realmente quiere hacer, por lo que mi código es probablemente inútil para usted ..

+0

La intención aquí es sonido.Es un rendimiento cuestionable enumerar la colección una vez por clave de pedido. Además, da miedo considerar la ejecución diferida de Linq y la interacción de Concat y Except. topFiles.Concat (files.Except (topFiles)) –

6

Aquí es un método que produce claves para ordenar

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

Así es como para llamarlo:

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

Thx, funcionó a la perfección. Tuve que pedir códigos de cuerda (modificados visualmente para usar cadena no char). Tuve que clasificar en rango, no alfa. E incluso captura códigos que no están en la lista, colocándolos en último lugar. –

0

puede almacenar la lista de orden deseado en una matriz

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

Di str mantiene su lista desordenada

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

Añadir su lista y que corresponde ordenar en una tabla de datos

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 Solicitar yuor lista para obtener yuor lista de espera

var result = from ls in dt.AsEnumerable() 
         orderby ls.Field<int>("Order") 
         select ls;  
Cuestiones relacionadas