使用aeson的形式键 - 值对的值

发布于 2025-02-08 12:53:12 字数 818 浏览 1 评论 0原文

我很难以形式解析JSON文本,

{
"Person1": {
"name": "John Doe",
"job" : "Accountant",
"id": 123
},
"Person2": {
"name": "Jane Doe",
"job" : "Secretary",
"id": 321
}}

如下所示,我定义了新的数据类型

data Person = Person
{ name :: String
, job  :: String
, id   :: Int } deriving Show

,但是在这种情况下,在定义fromjson的实例上遇到了麻烦。

现在,如果JSON文本是

{
 "People": [
    {
    "name": "John Doe",
    "job": "Accountant",
    "id": 123
    },
    {
    "name": "Jane Doe",
    "job": "Secretary",
    "id": 321
    }]
}

我可以写

instance FromJSON person where
    parseJSON = withObject "Person" $ \obj -> Person
    <$> obj .: "name"
    <*> obj .: "job"
    <*> obj .: "id"

的,但我不知道如何将此模式转换为其他格式。

I'm having trouble parsing JSON text in the form

{
"Person1": {
"name": "John Doe",
"job" : "Accountant",
"id": 123
},
"Person2": {
"name": "Jane Doe",
"job" : "Secretary",
"id": 321
}}

I define a new data type as follows

data Person = Person
{ name :: String
, job  :: String
, id   :: Int } deriving Show

But am having trouble defining an instance of FromJSON in this case.

Now if the JSON text were in the form of

{
 "People": [
    {
    "name": "John Doe",
    "job": "Accountant",
    "id": 123
    },
    {
    "name": "Jane Doe",
    "job": "Secretary",
    "id": 321
    }]
}

I could write

instance FromJSON person where
    parseJSON = withObject "Person" $ \obj -> Person
    <
gt; obj .: "name"
    <*> obj .: "job"
    <*> obj .: "id"

But I don't know how to translate this pattern to the other format.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

空城仅有旧梦在 2025-02-15 12:53:12

JSON字典,例如{“ foo”:“ bar”}可以将其解码为诸如map从“容器”软件包或hashmap中解码。来自无序的容器。一旦您拥有fromjson实例的人,只需使用aeson.decode获取MAP TEXT PERTENS。如果您想获得[Person],则可以进一步使用data.map.elems

例如:

#!/usr/bin/env cabal
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{- cabal:
build-depends: base, aeson, bytestring, containers
-}

import GHC.Generics
import qualified Data.Aeson as Aeson
import Data.Map (Map)
import Data.Maybe (fromMaybe)
import qualified Data.ByteString.Lazy.Char8 as BS

data Person = Person 
        { name :: String
        , job  :: String
        , id   :: Int
        } deriving (Show, Generic, Aeson.ToJSON, Aeson.FromJSON)

main :: IO ()
main = print . decodePersons . BS.pack =<< getContents

decodePersons :: BS.ByteString -> Map String Person
decodePersons = fromMaybe (error "fail") . Aeson.decode

有趣的一点是aeson.decode正在返回类型map String Person。一切都在那里进行完整的演示。

您可以使用输入进行测试:

% ./so.hs <<EOF
{
"Person1": {
"name": "John Doe",
"job" : "Accountant",
"id": 123
},
"Person2": {
"name": "Jane Doe",
"job" : "Secretary",
"id": 321
}}
EOF

要查看以下输出:

fromList [("Person1",Person {name = "John Doe", job = "Accountant", id = 123}),("Person2",Person {name = "Jane Doe", job = "Secretary", id = 321})]

如果要删除person1Person2标签,则只需使用data获取地图的元素.map.elems

A JSON dictionary, such as { "foo" : "bar" } can be decoded into Maps such as Map from the containers package or HashMap from unordered-containers. Once you have your FromJSON instance for Person then just use Aeson.decode to get a Map Text Person. If you'd like to get [Person] then you could further use Data.Map.elems.

For example:

#!/usr/bin/env cabal
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{- cabal:
build-depends: base, aeson, bytestring, containers
-}

import GHC.Generics
import qualified Data.Aeson as Aeson
import Data.Map (Map)
import Data.Maybe (fromMaybe)
import qualified Data.ByteString.Lazy.Char8 as BS

data Person = Person 
        { name :: String
        , job  :: String
        , id   :: Int
        } deriving (Show, Generic, Aeson.ToJSON, Aeson.FromJSON)

main :: IO ()
main = print . decodePersons . BS.pack =<< getContents

decodePersons :: BS.ByteString -> Map String Person
decodePersons = fromMaybe (error "fail") . Aeson.decode

The interesting bit is that Aeson.decode is returning a type Map String Person. Everything is is just there to make a complete demonstration.

You can test this with the input:

% ./so.hs <<EOF
{
"Person1": {
"name": "John Doe",
"job" : "Accountant",
"id": 123
},
"Person2": {
"name": "Jane Doe",
"job" : "Secretary",
"id": 321
}}
EOF

To see output of:

fromList [("Person1",Person {name = "John Doe", job = "Accountant", id = 123}),("Person2",Person {name = "Jane Doe", job = "Secretary", id = 321})]

If you want to drop the Person1 and Person2 tags then just get the elements of the Map using Data.Map.elems.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文