2011-10-29 15 views
5

Hola, tengo un tipo de búsqueda que almacena cadenas y datos.¿Cómo ordenar una búsqueda?

static Lookup<string, int> lookup; 
lookup = (Lookup<string, int>)list.ToLookup(i => i.IP, i => i.Number); 

Pero ahora tengo que resolver esto de búsqueda por los valores (número), y obtener las 10 teclas superiores con sus valores.

¿Cómo es esto posible?

+1

Estoy tratando de entender esto. ¿Por qué estás lanzando 'i.Number' a' string'? – James

+0

Hola lo siento, debería haber sido int. Lo cambiaré ahora, también marcaré una respuesta cuando vaya a casa y lo intente esta noche. Muchas gracias a todos. – sprocket12

Respuesta

2

No estoy seguro de por qué está lanzando una Lookup<string, int> a un Lookup<string, string>, pero la respuesta general que desea utilizar es:

var list = new List<Test> 
    { 
      new Test { IP = "A", Number = 1 }, new Test { IP = "A", Number = 3 }, new Test { IP = "A", Number = 4 }, 
      new Test { IP = "B", Number = 1 }, new Test { IP = "B", Number = 1 }, new Test { IP = "B", Number = 1 }, 
      new Test { IP = "C", Number = 1 }, 
      new Test { IP = "D", Number = 1 }, 
      new Test { IP = "E", Number = 1 }, new Test { IP = "E", Number = 1 }, new Test { IP = "E", Number = 1 } 
    }; 

var values = list.ToLookup(s => s.IP, s => s.Number) 
       .OrderByDescending(s => s.Count()) 
       .Take(10); 
+0

Hola, gracias por el esfuerzo extra en hacer una lista de prueba. – sprocket12

0

Eche un vistazo a la función Take() LINQ. Debería poder hacer algo como Take(10) para simplemente devolver 10 resultados. En cuanto a la clasificación, consulte la función OrderBy() que acepta una expresión lambda como un mecanismo de clasificación. Combinarlos a ambos debería darte lo que estás buscando.

1

Ve a buscar a una cola de prioridad (se puede encontrar uno en http://www.itu.dk/research/c5/). Itere sobre su búsqueda e inserte un elemento IComparable creado a partir de cada entrada en la búsqueda, en la cola de prioridad. Seleccione los diez elementos principales de la cola de prioridad. O simplemente ordénelos por el recuento como la clave.

var lookup = list.ToLookup(l => l.IP, l => l.Number); 
var topten = lookup.OrderByDescending(l => l.Count()) 
        .Take(10); 

foreach (var item in topten) 
{ 
    Console.WriteLine("{0}: {1}", item.Key, item.Count()); 
} 

Tenga en cuenta que la clasificación tendrá, en el mejor O (nlogn) mientras que un buen rendimiento, cola de prioridad basado en heap tendrá O (log n) el rendimiento. Si la colección no es grande, la clasificación es más simple dado el soporte integrado para ella y no necesita una clase intermedia para admitir la implementación de la cola de prioridad.

+0

Hola, tu respuesta es correcta, sin embargo, no pude marcar dos respuestas como correctas. Muchas gracias por su ayuda. – sprocket12

2

Lamentablemente, los elementos dentro de una búsqueda no se pueden reordenar.

Pero el método ToLookup() tiene una buena propiedad de que los elementos en todas las agrupaciones tienen el mismo orden que los elementos en la secuencia original.

Esto significa que con un poco de gimnasia Linq, se puede lograr lo que desea mediante el uso de GroupBy:

var l = (from l in list 
     // group elements by key 
     group l by l.IP into g 
     // for each group order the elements and take top 10 
     select new { g.Key, Items = g.OrderBy(g1 => g1.Number).Take(10)} into g2 
     // flaten group into an enumerable using select many 
     from g in g2.Items 
     select g) 
     // get the desired lookup containing the top 10 ordered elements for each key 
     .ToLookup(g => g.IP, g => g.Number); 
+0

Ohhh, ¿Quiere las diez mejores teclas y no las diez primeras por conteo? Eché de menos eso. –

+0

"los elementos en todas las agrupaciones tienen el mismo orden que los elementos en la secuencia original" - eso es bueno saberlo. – Homer