How to sort a lookup?

我只是一个虾纸丫 提交于 2020-06-27 07:14:10

问题


Hi I have a lookup type that stores strings and ints.

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

But now I need to sort this lookup by the values (number), and get the top 10 keys with their values.

How is this possible?


回答1:


I'm not sure why you are casting a Lookup<string, int> to a Lookup<string, string>, but the general answer you want is:

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



回答2:


Unfortunately elements inside a Lookup cannot be reordered.

But the ToLookup() method has a nice property that elements in all the groupings have the same order as the elements in the original sequence.

This means that with some Linq gymnastics, you can achieve what you want by using 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);



回答3:


Go find a Priority Queue (you can find one at http://www.itu.dk/research/c5/). Iterate over your look up and insert an IComparable item created from each entry in the look up, into the priority queue. Select the top ten items from the priority queue. Or just sort them by the count as the key.

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

Note that sorting will have at best O(nlogn) performance while a good, heap-based priority queue will have O(logn) performance. If the collection isn't large, sorting is simpler given the built in support for it and not needing an intermediate class to support the priority queue implementation.




回答4:


Take a look at the Take() LINQ function you should be able to do something like Take(10) to just return 10 results. As for sorting, check out the OrderBy() function that accepts a lambda expression as a sorting mechanism. Combining them both should give you what you're after.



来源:https://stackoverflow.com/questions/7942207/how-to-sort-a-lookup

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!