如何将Seq[A]过滤为Option[A]?匹配元素过多时抛出异常
Scala 简洁实现:过滤Seq为Option且多元素时抛异常
方式一:紧凑的条件判断写法
直接在过滤后通过条件判断处理,比match表达式更简洁直观:
val filtered = values.filter(_.something) val expected: Option[MyType] = if (filtered.size > 1) throw new AssertionError("测试设置错误") else filtered.headOption
方式二:自定义扩展方法(复用性优先)
如果这类操作在测试中频繁出现,建议封装成序列的扩展方法,符合Scala惯用的语法风格:
// 定义隐式扩展类 implicit class SingleOptionSeqOps[A](private val seq: Seq[A]) extends AnyVal { def singleOptionOrThrow(predicate: A => Boolean, errorMsg: String): Option[A] = { val matched = seq.filter(predicate) matched.size match { case s if s > 1 => throw new AssertionError(errorMsg) case _ => matched.headOption } } } // 调用示例 val expected: Option[MyType] = values.singleOptionOrThrow(_.something, "测试设置错误")
方式三:利用foldLeft单次遍历(性能优化)
如果序列元素较多,不想先过滤再统计大小(两次遍历),可以用foldLeft一次完成过滤、计数和结果收集:
val expected: Option[MyType] = values.foldLeft((Option.empty[MyType], 0)) { case ((result, count), elem) if elem.something => if (count >= 1) throw new AssertionError("测试设置错误") else (Some(elem), count + 1) case (acc, _) => acc }._1
这种方式只遍历序列一次,在处理大数据量时更高效。
内容的提问来源于stack exchange,提问作者M. Justin
相关产品推荐
相关产品推荐

