2011-10-29 6 views
5

Salut J'ai un type de recherche qui stocke les chaînes et les ints. Mais maintenant j'ai besoin de trier cette recherche par les valeurs (nombre), et obtenir les 10 premières clés avec leurs valeurs.Comment trier les recherches?

Comment est-ce possible?

+1

J'essaie de comprendre. Pourquoi lancez-vous 'i.Number' à' string'? – James

+0

Salut désolé, il aurait dû être int. Je vais le changer maintenant, je vais aussi marquer une réponse quand je rentre à la maison et l'essayer ce soir. Merci beaucoup à tous. – sprocket12

Répondre

2

Je ne sais pas pourquoi vous Jetant un Lookup<string, int> à un Lookup<string, string>, mais la réponse générale que vous voulez est:

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

Salut merci pour l'effort supplémentaire à faire une liste de test. – sprocket12

0

Jetez un oeil à la fonction LINQ Take() vous devriez être en mesure de faire quelque chose comme Take(10) à seulement 10 résultats. Pour ce qui est du tri, consultez la fonction OrderBy() qui accepte une expression lambda comme mécanisme de tri. En les combinant, les deux devraient vous donner ce que vous recherchez.

1

Go trouver une file d'attente prioritaire (vous pouvez en trouver un à http://www.itu.dk/research/c5/). Itérez sur votre recherche et insérez un élément IComparable créé à partir de chaque entrée dans la recherche, dans la file d'attente de priorité. Sélectionnez les dix premiers éléments de la file d'attente prioritaire. Ou juste les trier par le compte comme clé.

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

Notez que le tri aura au mieux O (nlogn) les performances tout en une bonne file d'attente prioritaire dans le tas aura O (logn) performance. Si la collection n'est pas grande, le tri est plus simple compte tenu de la prise en charge intégrée et sans avoir besoin d'une classe intermédiaire pour prendre en charge l'implémentation de la file d'attente prioritaire.

+0

Salut, votre réponse est correcte, mais je ne pouvais pas marquer deux réponses comme correctes. Merci beaucoup pour votre aide. – sprocket12

2

Malheureusement, les éléments à l'intérieur d'une recherche ne peuvent pas être réorganisés.

Mais la méthode ToLookup() a une belle propriété que les éléments de tous les groupes ont le même ordre que les éléments de la séquence d'origine.

Cela signifie que, avec un peu de gymnastique Linq, vous pouvez obtenir ce que vous voulez en utilisant 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, Il veut les dix premières touches et pas les dix premiers en nombre? J'ai totalement raté ça. –

+0

"les éléments dans tous les groupes ont le même ordre que les éléments de la séquence originale" - c'est bon à savoir. – Homer

Questions connexes