haskell /亚森 : output JSON as one object

标签 haskell ghc aeson

我有以下 Haskell 代码,它在 JSON 中编码数据类型 User 的列表并将其打印到标准输出:

{-# LANGUAGE OverloadedStrings #-}

module Main where

import Data.Aeson
import Data.Text
import qualified Data.ByteString.Lazy.Char8 as B

data User = User
    { id :: String
    , name :: String
    , address :: String
    } deriving (Show)

instance ToJSON User where
    toJSON (User id name address) = object
        [ pack id .= object
            [ "name" .= name
            , "address" .= address
            ]
        ]

users :: [User]
users = [ User "user 1" "name of user 1" "address of user 1"
        , User "user 2" "name of user 2" "address of user 2"
        ] 

main :: IO ()
main = B.putStrLn $ encode users

此时,代码产生以下输出:

[
  {
    "user 1": {
      "address": "address of user 1",
      "name": "name of user 1"
    }
  },
  {
    "user 2": {
      "address": "address of user 2",
      "name": "name of user 2"
    }
  }
]

但是,我想输出以下 JSON 结构(加入内部两个对象):

{
  "user 1": {
    "name": "name of user 1",
    "address": "address of user 1"
  },
  "user 2": {
    "name": "name of user 2",
    "address": "address of user 2"
  }
}

我将如何更改 toJSON 以打印所需的编码 JSON?

最佳答案

How will I have to change toJSON in order to print the desired encoded JSON?

您无法为 User 更改 toJSON 以打印所需的编码 JSON。问题不在 User 编码中,而在列表编码中。只是编码为 JSON 数组的简单列表。并且 JSON 数组没有值(所以你不能有 ["user 1":{...}] 因此每个对象都被包装到 {} 中) .这个问题可以用不同的方式解决。最简单的解决方案之一是为 User 列表编写自定义编码器。这是它的样子:

import qualified Data.HashMap.Strict as HM

usersEncode :: [User] -> Object
usersEncode = HM.unions . map (\(Object user) -> user) . map toJSON

然后在 main 中你可以这样调用它:

main = B.putStrLn $ encode $ usersEncode users

它会为您提供所需的输出。

诀窍在于 aeson 将对象存储为 HashMap,从 TextValueHashMap 被编码为 JSON 对象。因此,给定解决方案的想法是将每个用户转换为单例 HashMap,然后联合所有 HashMap

注意:它会从列表中删除具有重复 userId 的用户。

关于 haskell /亚森 : output JSON as one object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42861908/

相关文章:

haskell - 什么会导致 `stack build` 每次都取消注册本地依赖项?

performance - 部分评估右手操作符部分

haskell - 自动推导 (Map NewtypeOfText v) 的 ToJSON

haskell - 为什么 Yesod 中没有 ToJSON/FromJSON 的 Persistent 类型实例?

list - 如何知道导入中可用的完整功能列表是什么?

model-view-controller - Haskell 是否有任何 MVC Web 框架?

haskell - GHC 无需 Root 即可安装

json - 容错 JSON 解析

haskell - Show Haskell 的实例

haskell - 在 Haskell 中使用#if-#else-#endif