Scala/Scio类型不匹配:如何将Iterable[Double]转换为Double
错误原因
Scio全局top(n)算子的返回值是聚合后的单元素集合:元素类型为包含n个结果的Iterable[T],也就是说调用.top(100)后,SCollection类型已经从SCollection[Double]变成了SCollection[Iterable[Double]]。
后续.map(x => Result(x))里传入的x是Iterable[Double]类型,但Result样例类需要的构造参数是Double,因此触发类型不匹配错误。
修复方法
在top(100)之后加一步集合展开,把聚合得到的100个Double值打散成独立的流元素,再映射为Result对象即可,两种写法效果完全一致:
写法1:用flatten展开
@BigQueryType.fromQuery("SELECT weight_pounds FROM [bigquery-public-data:samples.natality]") class Row @BigQueryType.toTable case class Result(weight_pounds: Double) sc.typedBigQuery[Row]() .map(r => r.weight_pounds.getOrElse(0.0)) .top(100) .flatten // 将Iterable[Double]展开为单个Double元素 .map(Result(_)) .saveAsTypedBigQueryTable( Table.Spec(args("output")), writeDisposition = WRITE_TRUNCATE, createDisposition = CREATE_IF_NEEDED )
写法2:用flatMap展开
如果习惯用flatMap处理集合嵌套,也可以这么写:
.top(100) .flatMap(identity) .map(Result(_))
补充说明:全局top只会返回一个包含TopN结果的迭代器,展开后刚好是100条Double类型的独立记录,和定义的Result表结构完全匹配,不需要调整后续的BigQuery写入逻辑。
内容的提问来源于stack exchange,提问作者morpheus
相关产品推荐
相关产品推荐

