问题
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