c# - 我想使用 LINQ 获得最常见的值
问题描述
我正在尝试使用 C# 中的 LINQ 获取数组中最常见的值。
例如,
int[] input = {1, 1, 1, 3, 5, 5, 6, 6, 6, 7, 8, 8};
output = {1, 6}
int[] input = {1, 2, 2, 3 ,3, 3, 5}
output = {3}
请让我知道如何构建 LINQ。
请仔细阅读。这是使用 LINQ 选择最频繁值的另一个问题
我必须只选择最常见的值。下面的代码类似,但我不能使用 Take(5) 因为我不知道结果的数量。
int[] nums = new[] { 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7 };
IEnumerable<int> top5 = nums
.GroupBy(i => i)
.OrderByDescending(g => g.Count())
.Take(5)
.Select(g => g.Key);
这个输出是 {1, 2, 3, 4, 5} 但我的预期输出 = {1, 2}
请仔细阅读问题并回答。
谢谢并恭祝安康。
解决方案
只是为了添加过多的答案:
int[] input = { 1, 1, 1, 3, 5, 5, 6, 6, 6, 7, 8, 8 };
var result = input
.GroupBy(i => i)
.GroupBy(g => g.Count())
.OrderByDescending(g => g.Key)
.First()
.Select(g => g.Key)
.ToArray();
Console.WriteLine(string.Join(", ", result)); // Prints "1, 6"
[编辑]
如果有人觉得这很有趣,我将 .net 4.8 和 .net 5.0 之间的上述性能进行了如下比较:
(1) 添加了一个Comparer
类来检测所进行的比较次数:
class Comparer : IComparer<int>
{
public int Compare(int x, int y)
{
Console.WriteLine($"Comparing {x} with {y}");
return x.CompareTo(y);
}
}
(2) 修改调用OrderByDescending()
以传递 a Comparer
:
.OrderByDescending(g => g.Key, new Comparer())
(3) 将我的测试控制台应用程序多定位到“net48”和“net5.0”。
进行这些更改后,输出如下:
对于.net 4.8:
Comparing 1 with 3
Comparing 1 with 1
Comparing 1 with 2
Comparing 3 with 3
Comparing 3 with 2
Comparing 3 with 3
1, 6
对于 .net 5.0:
Comparing 3 with 1
Comparing 3 with 2
1, 6
如您所见,.net 5.0 得到了更好的优化。然而,对于 .net 框架(如 /u/mjwills 下文所述),使用MaxBy()
扩展以避免必须使用可能会更高效OrderByDescending()
- 但前提是检测表明排序导致性能问题。
推荐阅读
- java - Java Semaphore availablePermits with ThreadPool
- c++11 - Decltype Bug Gcc 无法编译
- tensorflow - 为什么我不能使用 CMake 用 VS2017 编译 tensorflow-r1.99?
- javascript - 如何在 jQuery 中使用 for 循环?
- android - 单击可扩展列表视图中的子项后如何打开新活动
- python-3.x - 参数“c”和“cmap”在 matplotlib 散点图中如何表现?
- python-3.x - 使用函数或其他方法在两个列表之间的特定索引中查找元素
- c++ - 在函数中操作 std::array
- javascript - 使用jQuery触发单选按钮onclick事件
- java - view.jsp 和 render 方法的 Liferay 基本实现策略