gpt4 book ai didi

json - Elm解码未知json结构

转载 作者:行者123 更新时间:2023-12-04 03:31:47 25 4
gpt4 key购买 nike

我刚刚开始使用 Elm 使用我正在开发的 Rest API 进行一些前端原型(prototype)设计。通常,API 返回可以解码的“合理”数据结构,因为键和值类型是众所周知的,但有几种资源类型返回 data仅具有没有预定结构的原始 json 的条目。

到目前为止,我所阅读的所有内容似乎都假设您知道要解码的数据的结构,而在纯 js 中,循环键并反射(reflect)类型以确定在运行时应如何处理它们相对容易.我还没有看到在 Elm 中处理此类数据的明确路径。

例如。,

{
"name":"foo",
"data": {
"bar": [{"baz":123}, "quux"]
},
...
}

我想知道当前是否可以解析 data 的值进入类似于
function go(obj)
for key in keys(foo)
if foo[key] is an object
go(foo[k])
else if foo[key] is an array
map(go, foo[k])
...

具体来说:
  • 目前是否可以在 Elm 中处理未知、可能深度嵌套和异构的 json 数据?
  • 如果是这样,您能否就作者如何对此类数据进行解码提供关键概念或高级直觉?
  • 最佳答案

    是的,可以编写通用解码器。您可以首先定义一个包含所有可能 Json 类型的联合类型:

    type JsVal
    = JsString String
    | JsInt Int
    | JsFloat Float
    | JsArray (List JsVal)
    | JsObject (Dict String JsVal)
    | JsNull

    现在您可以使用 Json.Decode.oneOf尝试每一种可能性。

    import Json.Decode as D exposing (Decoder)
    import Dict exposing (Dict)

    jsValDecoder : Decoder JsVal
    jsValDecoder =
    D.oneOf
    [ D.string |> D.andThen (D.succeed << JsString)
    , D.int |> D.andThen (D.succeed << JsInt)
    , D.float |> D.andThen (D.succeed << JsFloat)
    , D.list (D.lazy (\_ -> jsValDecoder)) |> D.andThen (D.succeed << JsArray)
    , D.dict (D.lazy (\_ -> jsValDecoder)) |> D.andThen (D.succeed << JsObject)
    , D.null JsNull
    ]

    Json.Decode.lazy JsArray 是必需的和 JsObject构造函数,因为它们是递归定义的。

    这个结构应该处理你扔给它的任何东西,而你的程序的其余部分将决定如何处理这种灵活的类型。

    编辑

    正如@Tosh 所指出的,这个解码器可以使用 map 来清理。而不是 andThen后跟 succeed :

    jsValDecoder : Decoder JsVal
    jsValDecoder =
    D.oneOf
    [ D.map JsString D.string
    , D.map JsInt D.int
    , D.map JsFloat D.float
    , D.list (D.lazy (\_ -> jsValDecoder)) |> D.map JsArray
    , D.dict (D.lazy (\_ -> jsValDecoder)) |> D.map JsObject
    , D.null JsNull
    ]

    关于json - Elm解码未知json结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40825493/

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