如何对查找进行排序?

时间:2011-10-29 22:56:47

标签: linq sorting lookup

您好我有一个存储字符串和整数的查找类型。

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

但现在我需要按值(数字)对此查找进行排序,并使用其值获取前10个键。

这怎么可能?

4 个答案:

答案 0 :(得分:3)

不幸的是,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);

答案 1 :(得分:2)

我不确定为什么要将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);

答案 2 :(得分:1)

找到优先级队列(您可以在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)性能。如果集合不大,则由于内置支持并且不需要中间类来支持优先级队列实现,因此排序更简单。

答案 3 :(得分:0)

看看Take() LINQ函数,您应该能够执行Take(10)之类的操作,只返回10个结果。至于排序,请查看接受lambda表达式的OrderBy()函数作为排序机制。将两者结合起来应该可以为你提供所需要的东西。