Scala 如何将带引号深层嵌套数组转换为array<array<array<array<double>>>类型
Scala 深层嵌套字符串数组转四层Double嵌套数组的可行方案
核心思路
你拿到的输入本质是字符串包裹的合法JSON格式嵌套数组,不需要手动写字符串拆分逻辑,借助成熟的JSON解析能力即可完成转换,适配两种常见使用场景:普通Scala应用、Spark SQL场景。
场景1:普通Scala应用转换为原生Scala嵌套数组
- 优先选择成熟的JSON解析库(如circe、play-json),避免手动拆分字符串导致的格式兼容问题(如数组元素间的空格、数值转义等)
- 先定义类型别名简化四层嵌套的类型声明:
// 对应目标结构 Array[Array[Array[Array[Double]]]] type NestedDouble4 = Array[Array[Array[Array[Double]]]] - 参考解析示例(以circe库为例):
import io.circe.parser._ // 带外层引号的原始输入字符串 val rawInput = "\"[[[[1962.717452,24087.495431], [1965.762332,24083.308721]]]]\"" // 第一步清理外层包裹的字面引号、转义字符 val cleanJsonStr = rawInput.stripPrefix("\"").stripSuffix("\"").replace("\\\"", "\"") // 执行解析,失败时抛出明确异常 val parsedResult = decode[NestedDouble4](cleanJsonStr) match { case Right(value) => value case Left(err) => throw new IllegalArgumentException(s"嵌套数组解析失败: ${err.getMessage}") }
场景2:Spark SQL 转换为目标 array<array<array<array<double>>> 类型
如果你的转换需求是在Spark计算场景下,无需引入第三方库,直接用Spark内置函数即可实现,结果天然匹配指定的SQL类型:
- 首先定义对应嵌套结构的Schema:
import org.apache.spark.sql.types._ // 严格对应目标类型 array<array<array<array<double>>> val targetSchema = ArrayType(ArrayType(ArrayType(ArrayType(DoubleType)))) - 结合内置函数完成字符串清洗、类型转换:
import org.apache.spark.sql.functions._ // 假设inputDF中raw_nested_str列存储的是带外层引号的嵌套数组字符串 val resultDF = inputDF // 正则清理字符串首尾包裹的多余双引号 .withColumn("clean_str", regexp_replace(col("raw_nested_str"), "^\"|\"$", "")) // 按照指定Schema解析为嵌套数组,可配置严格模式避免脏数据静默丢失 .withColumn("nested_arr", from_json(col("clean_str"), targetSchema))
常见踩坑提示
- 不要手动用split拆分字符串:示例中的数组元素间存在逗号加空格的分隔格式,手动拆分极易带入空格字符导致Double转换失败
- 优先用Double类型解析:示例中的数值为高精度小数,若用Float类型解析会出现精度损失
- 注意处理外层多余引号:从CSV、部分数据源读取的字符串会额外包裹一层双引号,若不先清洗会导致解析时将整体字符串识别为JSON字符串而非数组结构
内容的提问来源于stack exchange,提问作者YWILLS
相关产品推荐
相关产品推荐

