我已经执行了一个Linq查询,其中我根据呼叫和总计时长进行分组,一切都在按照预期进行.然而,问题是,作为输出,我得到了太多的结果.分组后,我想得到最多10个排名靠前的结果,并将休息组合到"休息"组.有什么办法可以用Linq来做到这一点吗?

以下是我当前查询的一个示例:

  IEnumerable<DataModel> data = this.Data
    .GroupBy(g => #here is regex match#)
    .Select(s => new DataModel
    {
      CallerNumber = s.Key,
      Duration = TimeSpan.FromTicks(s.Sum(c => c.Duration.Ticks)),
    })
    .Where(w => !string.IsNullOrEmpty(w.CallerNumber))
    .OrderByDescending(o => o.Duration);

我可以在查询的末尾使用.Take(10);,但如何将所有剩余的部分组合成"休息"部分?我的意思是,我会得到前10名的记录,但在第11、12、13、14位等位置上还有更多的记录现在没有显示.如何将它们组合在一起并显示为输出列表中的第11项.

  IEnumerable<DataModel> data = this.Data
    .GroupBy(g => #here is regex match#)
    .Select(s => new DataModel
    {
      CallerNumber = s.Key,
      Duration = TimeSpan.FromTicks(s.Sum(c => c.Duration.Ticks)),
    })
    .Where(w => !string.IsNullOrEmpty(w.CallerNumber))
    .OrderByDescending(o => o.Duration)
    .Take(10);

EDIT:

我的 idea 是,假设我有电话号码:

050321        4:30
045345        2:00
050321        4:00
045345        6:00
076843        1:00
050321        1:00
032345        3:00
043453        2:00
032345        3:00

这就是我想要实现的目标(比方说我想进入前3名,其余的加在一起):

050321        9:30
045345        8:00
032345        6:00
Rest          3:00

推荐答案

我建议twice组,即

int top = 10;

var data = this
  .Data
  .GroupBy(item => # here is regex match #)
  .Select(group => (key : group.Key, 
                    total : group.Sum(item => item.Duration.Ticks)))
  .OrderByDescending(pair => pair.total)
  .Select((pair, index) => (pair.key, pair.total, index))
  .GroupBy(rec => rec.index < top ? rec.key : "Rest",
           rec => rec.total)
  .Select(group => new DataModel() {
     CallerNumber = group.Key,
     Duration = TimeSpan.FromTicks(group.Sum(item => item))
   });

其 idea 是将索引为11, 12, .."Rest"关键字下的所有项目分别设置为order by descendinggroup by:

int top = 10;

...

.GroupBy(rec => rec.index < top ? rec.key : "Rest",
         rec => rec.total)

如果rec有足够小的index(0..9),则它的key被保留,否则它被归入"Rest" key.

Fiddle

如果您想删除key为空的组,您可以将其过滤掉:

var data = 
  ...
  .GroupBy(item => # here is regex match #)
  .Where(group => !string.IsNullOrEmpty(group)) 
  ...

或者把它加到"Rest":

var data = 
  ...
  .Select(group => (key : group.Key, 
                    total : group.Sum(item => item.Duration.Ticks)))
  .OrderBy(pair => string.IsNullOrEmpty(pair.key) ? 1 : 0)
  .ThenByDescending(pair => pair.total)
  ...

Csharp相关问答推荐

用C#在现有文档中插入一个ML字符串打破了一切

.NET将复杂的Dto序列化为SON字符串

有没有方法让ASP.NET Core模型绑定器使用私有设置器来设置属性?

处理. netstandard2.0项目中HttpClient.SslProtocol的PlatformNotSupportedException问题""

属性getter和setter之间的空性不匹配?

使用命令初始化可绑定属性

从Blob存储中提取tar.gz文件并将提取结果上载到另一个Blob存储

默认情况下,.NET通用主机(Host.CreateDefaultBuilder)中是否包含UseConsoleLifetime?

如何在Windows 11任务调度程序中每1分钟重复一次任务?

如何使datagridview的列具有响应性,以便不是所有列都更改其宽度

如何将此方法参数化并使其更灵活?

C#带主体的主构造函数?

从VS调试器而不是测试资源管理器运行的调试NUnitDotNet测试

Savagger使用Fastendpoint更改用户界面参数

VS 2022与VS 2019:如何/为什么创建额外的任务?

Content WithTargetPath实际上是有效的MSBuild项吗?

ASP.NET MVC数据批注验证组复选框

错误:此版本的Visual Studio无法打开以下项目

如何在一次数据库调用中为ASP.NET核心身份用户加载角色

Autofac -动态实例化:手动传递构造函数