gpt4 book ai didi

haskell /亚森 : output JSON as one object

转载 作者:行者123 更新时间:2023-12-04 03:13:50 26 4
gpt4 key购买 nike

我有以下 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com