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

如何使用Aeson解析器提取合并JSON对象所有数组值为单个数组

实现方案

核心思路

  • 先将JSON输入解析为Aeson的Object类型(键值对Map结构),自动忽略所有未知键名
  • 提取Object中所有的Value值
  • 将每个Value统一解析为指定元素类型的数组
  • 拼接所有数组得到最终结果

完整代码示例

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}

import Data.Aeson (FromJSON(..), Value, withObject, eitherDecode)
import Data.Aeson.Types (Parser)
import qualified Data.ByteString.Lazy.Char8 as BSL
import qualified Data.HashMap.Strict as HM
import Data.Foldable (toList)

-- 自定义解析函数:接收JSON Value,返回拼接后的数组
concatObjectArrays :: FromJSON a => Value -> Parser [a]
concatObjectArrays = withObject "array-containing object" $ \obj ->
  -- 遍历所有值解析为数组,再拼接
  fmap concat $ traverse parseJSON $ toList $ HM.elems obj

-- 可选:封装为自定义类型的FromJSON实例,方便直接调用
newtype MergedArray a = MergedArray { getMerged :: [a] }
  deriving (Show, Eq)

instance FromJSON a => FromJSON (MergedArray a) where
  parseJSON = fmap MergedArray . concatObjectArrays

-- 测试用例
main :: IO ()
main = do
  let testInput = BSL.pack "{ \"a\": [1,2,3], \"f\": [4,5,6], \"b\": [7,8,9]}"
  let result = eitherDecode testInput :: Either String (MergedArray Int)
  print $ fmap getMerged result
  -- 输出结果:Right [1,2,3,4,5,6,7,8,9]

补充说明

  • 你可以直接使用concatObjectArrays函数作为其他复杂解析逻辑的组成部分,也可以通过MergedArray封装类型直接对整个JSON做解析
  • 数组元素类型支持任意实现了FromJSON的类型,替换代码中的Int为你需要的类型即可
  • 如果某个键对应的值不是数组,解析会自动返回错误,符合所有键取值均为数组的预设条件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 21:09:03