gpt4 book ai didi

json - 解码递归多路树

转载 作者:行者123 更新时间:2023-12-02 01:44:44 25 4
gpt4 key购买 nike

我正在研究这种类型的递归树

type Node anyType
= Leaf Id (Maybe anyType) Name
| Tree Id (List (Node anyType)) Name

哪里

type Id
= Id Int
| Root

我正在尝试将这种 json 解码为它

{
"id": "root",
"entries": [
{
"id": 1,
"value": 0,
"name": "New Entry"
},
{
"id": 2,
"entries": [
{
"id": 4,
"value": 0,
"name": "New Entry"
}
],
"name": "New Entry"
}
],
"name": "Budget"
}

为了解码 Id 类型,我正在使用这些解码器

rootDecoder =
(Decode.field "id" Decode.string)
|> Decode.andThen
(\str ->
if str == "root" then
(Decode.succeed Root)

else
Decode.fail <| "[exactMatch] tgt: " ++ "root" ++ " /= " ++ str
)


intIdDecoder =
Decode.map Id (Decode.field "id" Decode.int)


idDecoder =
Decode.oneOf
[ rootDecoder
, intIdDecoder
]

为了解码树结构,我尝试了以下操作,使用 Json.Decode.Pipeline:

leafDecoder valueDecoder =
Decode.succeed Leaf
|> required "id" idDecoder
|> required "value" valueDecoder
|> required "name" Decode.string


treeDecoder valueDecoder =
Decode.succeed Tree
|> required "id" idDecoder
|> required "entries"
(Decode.list
(Decode.lazy
(\_ ->
Decode.oneOf
[ leafDecoder valueDecoder
, treeDecoder valueDecoder
]
)
)
)
|> required "name" Decode.string

但是当我尝试解码该结构时,出现以下错误:

The Json.Decode.oneOf at json.budget.entries[0] failed in the following 2 ways: (1) The Json.Decode.oneOf at json.id failed in the following 2 ways: (1) Problem with the given value: 1 Expecting an OBJECT with a field named `id` (2) Problem with the given value: 1 Expecting an OBJECT with a field named `id` (2) Problem with the given value: { "id": 1, "value": 0, "name": "New Entry" } Expecting an OBJECT with a field named `entries`

但我不明白为什么,因为字段 identries 都在那里,但它还是提示。

我做错了什么?

最佳答案

在您的 leafDecodertreeDecoder 中,您有以下几行:

leafDecoder valueDecoder =
Decode.succeed Leaf
|> required "id" idDecoder
-- rest of function omitted...

treeDecoder valueDecoder =
Decode.succeed Tree
|> required "id" idDecoder
-- rest of function omitted...

它们都会提取当前对象中的字段 id 的值,并将该值传递给 idDecoder,后者调用 Decode.oneOfrootDecoderintIdDecoder

但是,在您的 rootDecoderintIdDecoder 中,您有以下内容:

rootDecoder =
(Decode.field "id" Decode.string)
|> Decode.andThen
-- rest of function omitted...

intIdDecoder =
Decode.map Id (Decode.field "id" Decode.int)

这些解码器尝试从当前对象中提取名为 id 的字段的值。但是您向这些函数传递的是 id 属性的值,而不是包含此属性的对象。

如果您的 id 嵌套在仅包含 id 属性的对象中,这些解码器将起作用,例如:

{
"id": {"id": "root"},
"entries": [
{
"id": {"id": 1},
"value": 0,
"name": "New Entry"
},
...

修复方法是删除 rootDecoderintIdDecoder 中对 Decode.field 的调用,因为这些解码器已经传递了id 字段:

rootDecoder =
Decode.string
|> Decode.andThen
-- rest of function as before, and omitted for brevity...


intIdDecoder =
Decode.map Id Decode.int

关于json - 解码递归多路树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71070087/

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