如何对查找进行排序?

发布于 2024-12-12 19:38:54 字数 237 浏览 3 评论 0原文

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

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

但现在我需要按值(数字)对此查找进行排序,并获取前 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

枫林﹌晚霞¤ 2024-12-19 19:38:54

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

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);
⒈起吃苦の倖褔 2024-12-19 19:38:54

我不确定为什么您要将 Lookup 转换为 Lookup,但您想要的一般答案是:

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

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);
辞取 2024-12-19 19:38:54

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

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.

醉酒的小男人 2024-12-19 19:38:54

看一下 Take() LINQ 函数,您应该能够执行 Take(10) 之类的操作来仅返回 10 个结果。至于排序,请查看 OrderBy() 函数,该函数接受 lambda 表达式作为排序机制。将它们结合起来应该会给你你想要的东西。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文