Как отсортировать поиск? - PullRequest
7 голосов
/ 30 октября 2011

Привет У меня есть тип поиска, в котором хранятся строки и целые числа.

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

Но теперь мне нужно отсортировать этот поиск по значениям (число) и получить первые 10 ключей с их значениями.

Как это возможно?

Ответы [ 4 ]

3 голосов
/ 30 октября 2011

К сожалению, элементы внутри Lookup не могут быть переупорядочены.

Но у метода ToLookup () есть приятное свойство - элементы во всех группах имеют тот же порядок, что и элементы в исходной последовательности.

Это означает, что с помощью гимнастики Linq вы можете достичь желаемого с помощью 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);
2 голосов
/ 30 октября 2011

Я не уверен, почему вы приводите Lookup<string, int> к Lookup<string, string>, но вы хотите получить общий ответ:

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);
1 голос
/ 30 октября 2011

Идите и найдите приоритетную очередь (вы можете найти ее в http://www.itu.dk/research/c5/).. Переберите свой поиск и вставьте элемент IComparable, созданный из каждой записи в поиске, в очередь с приоритетами. Выберите первые десять элементов изочереди приоритетов. Или просто сортируйте их по количеству в качестве ключа.

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

Обратите внимание, что сортировка будет иметь наилучшую производительность O (nlogn), в то время как хорошая очередь с приоритетом на основе кучи будет иметь O (logn).производительность. Если коллекция не большая, сортировка проще, если встроенная поддержка для нее и отсутствие промежуточного класса для поддержки реализации очереди с приоритетами.

0 голосов
/ 30 октября 2011

Посмотрите на функцию Take() LINQ, вы должны иметь возможность сделать что-то вроде Take(10), чтобы просто вернуть 10 результатов. Что касается сортировки, посмотрите функцию OrderBy(), которая принимает лямбда-выражение в качестве механизма сортировки. Объединение их обоих должно дать вам то, что вы ищете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...