使用Aeson泛型来构造一个以值作为键来保存另一个值的JSON [英] Using Aeson generics to construct JSON with a value as key holding another value
问题描述
在尝试使用Aeson JSON库时,使用github gist API进行了一些修改.我遇到了与生成的ToJSON实例有关的问题,我不知道确切如何解决它.
Toying a bit with the github gist API while trying to get down with the Aeson JSON library. I've run into a problem with the generated ToJSON instance, and I don't know exactly how to solve it.
我需要在其中包含一个值,并且与该值关联的键也必须是一个值,而不是预定义的键名.显示起来有点容易.所需的输出是
I need to contain a value inside and the key that is associated to the value also needs to be a value and not a predefined key name. It's a bit easier to show. The desired output is,
{
"public": true,
"description": "Something..",
"files": {"This Thing.md": {"content": "Here we go!"}}
}
其中文件名的值用于保存内容,但是目前我知道了,
where the value of the filename is holding the content, but currently I get,
{
"public": true,
"description": "Something..",
"files": {"filename": "This Thing.md", "content": "Here we go!"}
}
不是我真正需要的.当前代码是
Which isn't really what I need. The current code is,
{-# LANGUAGE OverloadedStrings, DeriveGeneric #-}
import Data.Text (Text)
import Data.Aeson
import GHC.Generics
data GistContent = GistContent
{ filename :: Text
, content :: Text
} deriving (Show, Generic)
instance ToJSON GistContent
data Gist = Gist
{ description :: Text
, public :: Bool
, files :: GistContent
} deriving (Show, Generic)
instance ToJSON Gist
在可能的假设下,如何查看我的数据结构以获取所需的输出?.如果使用泛型无法实现,那么如何使用ToJSON实例(我可以?不太清楚那里的结构)吗?
Under the assumption that it is possible, how would my datastructure need to look to get the desired output?.. And if that's not possible using the generics, how'd I got about it using the ToJSON instance (I can't quite figure out the structure there either)?
推荐答案
您的问题源于不正确的架构. files
当前只能包含一个GistContent
,这是不必要的限制.相反,您需要一个GistContent
s的列表:
Your problem stems from an incorrect schema. files
can currently only contain one GistContent
, which is unnecessarily limiting. Instead, you'd want to have a list of GistContent
s:
data Gist = Gist
{ description :: Text
, public :: Bool
, files :: [GistContent]
} deriving (Show, Generic)
现在考虑对Gist
的另一个约束:每个GistContent
必须具有不同的filename
.可以强制执行此操作的数据结构为 Data.HashMap.Strict.HashMap
.从GistContent
中取出filename
并使用文件名作为键:
Now consider another constraint on Gist
: each GistContent
must have a different filename
. A data structure that would enforce this would be Data.HashMap.Strict.HashMap
. Taking the filename
out of GistContent
and using the filename as a key:
data GistContent = GistContent
{ content :: Text
} deriving (Show, Generic)
data Gist = Gist
{ description :: Text
, public :: Bool
, files :: HashMap Text GistContent
} deriving (Show, Generic)
一切顺利.
这篇关于使用Aeson泛型来构造一个以值作为键来保存另一个值的JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!