2011-10-29 16 views
5

Witam Mam typ wyszukiwania, który przechowuje ciągi i ints.Jak sortować wyszukiwanie?

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

Ale teraz muszę posortować to wyszukiwanie według wartości (liczba) i uzyskać 10 najlepszych kluczy z ich wartościami.

Jak to jest możliwe?

+1

Staram się to zrozumieć. Dlaczego rzutujesz 'i.Number' na' string'? – James

+0

Cześć przepraszam, to powinno być int. Zmienię to teraz, również Złą oznakuję odpowiedź, kiedy idę do domu i wypróbuję to dziś wieczorem. Wielkie dzięki wszystkim. – sprocket12

Odpowiedz

2

Nie jestem pewien, dlaczego jesteś odlewania Lookup<string, int> do Lookup<string, string>, ale ogólna odpowiedź chcesz to:

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

Cześć dzięki za dodatkowy wysiłek w tworzeniu listy testowej. – sprocket12

0

Spójrz na funkcję LINQ Take(), powinieneś być w stanie zrobić coś w rodzaju Take(10), aby zwrócić 10 wyników. Jeśli chodzi o sortowanie, sprawdź funkcję OrderBy(), która akceptuje wyrażenie lambda jako mechanizm sortujący. Połączenie ich obu powinno dać ci to, czego szukasz.

1

Go znaleźć kolejki priorytetowej (można znaleźć w http://www.itu.dk/research/c5/). Powtórzyć wyszukiwanie i wstawić element ICompowalny utworzony z każdego wpisu w wyszukiwaniu do kolejki priorytetów. Wybierz dziesięć pierwszych pozycji z kolejki priorytetów. Lub posortuj je według liczby jako klucza.

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

Zauważ, że sortowania będą miały w najlepszym O (nlogn) Wydajność podczas gdy dobre, oparte na sterty priorytet kolejki będą miały O (logn) wydajność. Jeśli kolekcja nie jest duża, sortowanie jest prostsze, biorąc pod uwagę wbudowane wsparcie dla niego i niepotrzebujące klasy pośredniej do obsługi implementacji kolejki priorytetów.

+0

Witam, twoja odpowiedź jest poprawna, jednak nie mogłem oznaczyć dwóch odpowiedzi jako poprawnych. Wielkie dzięki za Twoją pomoc. – sprocket12

2

Niestety elementów wewnątrz wyszukiwania nie można zmienić.

Ale metoda ToLookup() ma ładną właściwość, że elementy we wszystkich grupach mają tę samą kolejność, co elementy w oryginalnej sekwencji.

Oznacza to, że w przypadku niektórych gimnastyki LINQ, można osiągnąć to, co chcesz za pomocą 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, chce dziesięciu najlepszych kluczy, a nie pierwszą dziesiątkę według liczby? Całkowicie tego nie zauważyłem. –

+0

"elementy we wszystkich grupach mają tę samą kolejność, co elementy w pierwotnej sekwencji" - to dobrze wiedzieć. – Homer