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

Scala Play JSON:遍历JsArray/JsObject统计值为Null的键出现次数

Counting Null-Valued Keys with Play JSON

Hey there! Let's figure out how to count those null-valued keys in your JSON using Play JSON—no external libraries needed. I’ve run into this exact confusion before, so let’s break it down step by step.

Why You’re Seeing "map doesn’t exist" Errors

First up: Play JSON’s JsObject and JsArray aren’t directly traversable collections. You can’t call map on them directly because they’re wrapper classes—you need to access their internal sequence properties first:

  • For JsObject, use the fields property (it returns a Seq[(String, JsValue)] of all key-value pairs)
  • For JsArray, use the value property (it returns a Seq[JsValue] of all elements)

Recursive Solution for Nested JSON

Since JSON is often nested (objects inside objects, arrays of objects), we’ll write a recursive function to traverse every level and count all keys with JsNull values. Here’s the code:

import play.api.libs.json._

def countNullKeys(json: JsValue): Int = json match {
  // Handle objects: check each key's value, count nulls, then recurse into the value
  case JsObject(fields) =>
    fields.foldLeft(0) { (totalCount, (key, value)) =>
      // Add 1 if this key's value is null
      val currentNull = if (value == JsNull) 1 else 0
      // Add current null count plus any nulls in nested structures
      totalCount + currentNull + countNullKeys(value)
    }
  // Handle arrays: recurse into each element and sum the counts
  case JsArray(elements) =>
    elements.foldLeft(0)(_ + countNullKeys(_))
  // All other JSON types (strings, numbers, nulls not tied to a key) contribute 0
  case _ => 0
}

Test It Out

Let’s use a sample university domain JSON to see it in action:

// Sample university JSON with nested nulls
val universityJson = Json.parse("""
{
  "name": "Stanford University",
  "primary_domain": null,
  "secondary_domains": [
    {"domain": "cs.stanford.edu", "contact": null},
    {"domain": "med.stanford.edu", "contact": "med-admin@stanford.edu"}
  ],
  "admin": {
    "name": null,
    "email": "admin@stanford.edu"
  }
}
""")

// Should return 3: primary_domain, contact (CS dept), name (admin)
println(countNullKeys(universityJson))

If You Only Need Top-Level Nulls

If you don’t care about nested nulls and just want to count top-level keys with null values, simplify the function:

def countTopLevelNullKeys(json: JsValue): Int = json match {
  case JsObject(fields) => fields.count(_._2 == JsNull)
  case _ => 0
}

Fixing Your Pattern Matching Issues

Chances are your earlier pattern matching failed because you didn’t extract the internal collections. Instead of writing case JsObject =>, use case JsObject(fields) to get access to the key-value pairs. Same for arrays: case JsArray(elements) lets you iterate over the array’s contents.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:59:42