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

如何用Circe或Jsoniter编写自定义解码器仅获取数组长度?

用Circe和Jsoniter实现仅提取JSON数组长度的自定义解码器

针对你的需求——并发调用API时仅获取myArray的长度,Circe和Jsoniter都能通过自定义解码器高效实现,甚至可以避免加载整个JSON到内存,非常适合高并发场景。

Circe 实现方案

Circe提供了两种思路,按需选择:

1. 轻量解码(适合小体积JSON)

直接定义只包含目标字段的结构,自动生成解码器后提取长度:

import io.circe._
import io.circe.generic.semiauto._
import io.circe.parser.decode

// 只定义需要的字段,其他字段自动忽略
case class ApiResult(myArray: List[Any])

// 自动生成解码器
implicit val resultDecoder: Decoder[ApiResult] = deriveDecoder[ApiResult]

// 解析并获取数组长度
val jsonStr = """{"myArray":[{"a":1},{"b":2}],"cursor":"abc"}"""
val lengthResult: Either[Error, Int] = decode[ApiResult](jsonStr).map(_.myArray.size)

2. 流式解析(适合大体积JSON)

用Circe的jawn流式处理,只遍历myArray统计元素数量,不加载整个数组:

import io.circe.jawn.parse
import jawn.ast.JValue

val jsonStr = """{"myArray":[{"a":1},{"b":2}],"cursor":"abc"}"""
val lengthResult = parse(jsonStr).map { json =>
  json.asObject.flatMap(_("myArray")) match {
    case Some(JValue.JArray(arr)) => arr.size
    case _ => 0 // 处理字段不存在或类型错误的情况
  }
}

Jsoniter 实现方案

Jsoniter Scala以高性能著称,默认流式解析,非常适合高并发场景,自定义解码器可以直接跳过无关内容:

import com.github.plokhotnyuk.jsoniter_scala.core._

// 定义要提取的结果结构
case class ArrayInfo(length: Int, cursor: String)

// 自定义解码器,只处理目标字段
implicit val arrayInfoCodec: JsonValueCodec[ArrayInfo] = new JsonValueCodec[ArrayInfo] {
  override def decodeValue(in: JsonReader, default: ArrayInfo): ArrayInfo = {
    var len = 0
    var cursorVal = ""
    in.beginObject()
    while (in.hasNext) {
      in.readObjectKeyAsCharSequence() match {
        case "myArray" =>
          in.beginArray()
          while (in.hasNext) {
            in.skip() // 跳过数组元素,不解析
            len += 1
          }
          in.endArray()
        case "cursor" => cursorVal = in.readString()
        case _ => in.skip() // 忽略其他字段
      }
    }
    in.endObject()
    ArrayInfo(len, cursorVal)
  }

  override def encodeValue(x: ArrayInfo, out: JsonWriter): Unit = () // 不需要编码,留空即可
}

// 解析使用
val jsonStr = """{"myArray":[{"a":1},{"b":2}],"cursor":"abc"}"""
val result = readFromString(jsonStr)
println(result.length) // 输出2
println(result.cursor) // 输出abc

选型建议

  • 追求开发效率和生态完善选Circe,API更简洁易读;
  • 追求极致性能和高并发场景选Jsoniter,流式解析的内存占用更低。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:30:59