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

如何根据指定分箱范围将Scala集合划分为对应子集?

Scala按指定分箱范围对Sample列表分组的最优实现

需求说明

我们有一个包含大量Sample实例的List,每个Sample包含id(String)和value(Double)属性,需要根据给定的分箱范围列表List(5,50,100),将样本划分为以下有序分组:

  1. 值为0的样本
  2. 值大于0且≤5的样本
  3. 值大于5且≤50的样本
  4. 值大于50且≤100的样本
  5. 值大于100的样本

基础实现方案(直观易读)

这种方案代码简洁直观,适合样本量中等的场景:

case class Sample(id: String, value: Double)

val samples: List[Sample] = List(
  Sample("a", 0),
  Sample("b", 2),
  Sample("c", 20),
  Sample("d", 50),
  Sample("e", 100),
  Sample("f", 1000)
)

val buckets = List(5, 50, 100)

// 一次遍历分离0值样本和非0样本
val (zeroGroup, nonZeroSamples) = samples.partition(_.value == 0)

// 构建完整的分箱区间:(0,5], (5,50], (50,100], (100, +∞)
val bucketIntervals = (0.0 +: buckets).zip(buckets) :+ (buckets.last, Double.PositiveInfinity)

// 按区间筛选非0样本,保持分组顺序
val nonZeroGroups = bucketIntervals.map { case (lower, upper) =>
  nonZeroSamples.filter(s => s.value > lower && s.value <= upper)
}

// 合并所有分组得到最终结果
val result = zeroGroup :: nonZeroGroups

高性能实现方案(适合超大规模样本)

当处理百万级以上的大列表时,减少遍历次数能显著提升性能,以下方案通过groupBy仅遍历非0样本一次:

case class Sample(id: String, value: Double)

val samples: List[Sample] = List(
  Sample("a", 0),
  Sample("b", 2),
  Sample("c", 20),
  Sample("d", 50),
  Sample("e", 100),
  Sample("f", 1000)
)

val buckets = List(5, 50, 100)

// 分离0值样本
val (zeroGroup, nonZeroSamples) = samples.partition(_.value == 0)

// 给每个非0样本分配对应的分箱索引
val indexedGroups = nonZeroSamples.groupBy { sample =>
  // 找到第一个≥样本值的分箱位置,无匹配则分配到最后一个分组
  buckets.indexWhere(_ >= sample.value) match {
    case -1 => buckets.size
    case idx => idx
  }
}

// 按分箱顺序提取分组,确保结果有序
val nonZeroGroups = (0 to buckets.size).map(idx => indexedGroups.getOrElse(idx, Nil)).toList

// 合并结果
val result = zeroGroup :: nonZeroGroups

结果验证

两种方案最终得到的result都与需求输出完全一致:

List(
  List(Sample("a", 0)),
  List(Sample("b", 2)),
  List(Sample("c", 20), Sample("d", 50)),
  List(Sample("e", 100)),
  List(Sample("f", 1000))
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 00:30:45