You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从IGrouping分组结果中获取每组的首个元素?

获取GroupBy分组中的首个元素

嘿,这个需求其实用Linq就能轻松搞定!因为GroupBy返回的每个IGrouping<TKey, TElement>本身就是一个可枚举集合,你只需要对每个分组调用First()(或者FirstOrDefault(),用来处理空分组的极端情况),就能拿到组内的第一个元素。

结合你提供的Extract方法,我们可以直接在分组后的result上链式调用Select来提取目标元素,具体修改后的代码如下:

void Extract() {
    List<DataHolder> data = new List<DataHolder>();
    Random r = new Random();
    DateTime d = new DateTime(2019, 9, 19, 7, 0, 0);
    
    // 生成测试数据
    for (int i = 0; i < 100; i++) {
        DataHolder dh = new DataHolder();
        TimeSpan t = TimeSpan.FromSeconds(r.Next(0, 14400));
        dh.OID = i;
        dh.Value = r.Next(50);
        dh.Snapshottime = d.Add(t);
        data.Add(dh);
    }

    // 按时间排序数据
    List<DataHolder> sortedList = data.OrderBy(o => o.Snapshottime).ToList();
    TimeSpan interval = new TimeSpan(0, 15, 0);
    
    // 按15分钟间隔分组并按组键排序
    var groupedData = sortedList.GroupBy(x => x.Snapshottime.Ticks / interval.Ticks)
        .OrderBy(x => x.Key);

    // 提取每个分组的首个元素
    var firstElementsPerGroup = groupedData.Select(group => group.First());

    // 转换成List方便后续处理(可选)
    List<DataHolder> firstElementsList = firstElementsPerGroup.ToList();

    // 示例:打印验证结果
    foreach (var item in firstElementsList)
    {
        Console.WriteLine($"OID: {item.OID}, 时间: {item.Snapshottime}, 值: {item.Value}");
    }
}

public class DataHolder {
    public int OID { get; set; }
    public double Value { get; set; }
    public DateTime Snapshottime { get; set; }
}

小补充:

  • First() vs FirstOrDefault():如果能确保每个分组都至少有一个元素(比如你的场景,分组基于非空的已排序列表),用First()就足够;如果存在分组为空的可能性,FirstOrDefault()会返回对应类型的默认值(比如null,因为DataHolder是引用类型),避免抛出异常。
  • 原代码里data.OrderBy(o => o.Snapshottime).ToList();这行其实没有生效,因为Linq方法不会修改原集合,只会返回新集合,所以下面重新排序并赋值给sortedList的做法是正确的,不用改动。

内容的提问来源于stack exchange,提问作者Josef

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:00:53