给出以下JSON:
[
{
"id": 0,
"name": "Item 1",
"desc": "The first item"
},
{
"id": 1,
"name": "Item 2"
}
]
如何将其解码为以下模型:
type alias Model =
{ id : Int
, name : String
, desc : Maybe String
}
答案 0 :(得分:17)
Brian Hicks在JSON解码器上有一系列帖子,您可能希望专门查看Adding New Fields to Your JSON Decoder
(它处理您可能会或可能不会从JSON对象接收字段的场景)。
首先,您可能想要使用elm-decode-pipeline package。然后,您可以使用optional
function声明您的desc
字段可能不存在。正如Brian在文章中指出的那样,您可以使用maybe
中的the core Json.Decode
package解码器,但它会为任何失败产生Nothing
,而不仅仅是{{} 1}}。 是一个nullable
解码器,如果您不想使用管道模块,也可以考虑使用它。
你的解码器看起来像这样:
null
答案 1 :(得分:9)
因此,如果您正在寻找不需要Json.Decode.Pipeline
的零依赖解决方案。
import Json.Decode as Decode exposing (Decoder)
modelDecoder : Decoder Model
modelDecoder =
Decode.map3 Model
(Decode.field "id" Decode.int)
(Decode.field "name" Decode.string)
(Decode.maybe (Decode.field "desc" Decode.string))
如果你想使用Model
构造函数作为applicative functor(因为你需要更多8个项目)来做这件事。
import Json.Decode as Decode exposing (Decoder)
import Json.Decode.Extra as Decode
modelDecoder : Decoder Model
modelDecoder =
Decode.succeed Model
|> Decode.andMap (Decode.field "id" Decode.int)
|> Decode.andMap (Decode.field "name" Decode.string)
|> Decode.andMap (Decode.maybe (Decode.field "desc" Decode.string))
这两者都可以List
与Decode.list modelDecoder
一起使用。我希望应用函数在标准库中,但是您必须进入所有* -extra库才能获得这些功能。了解应用程序仿函数如何工作将有助于您了解更多内容,因此我建议您阅读它们。解码管道解决方案抽象了这个简单的概念,但是当您遇到Result.andMap
或任何其他andMap
的需求时,因为您的模块不是mapN
或一个DSL,你将知道如何找到你的解决方案。
答案 2 :(得分:2)
import Html exposing (..)
import Json.Decode as Decode exposing (Decoder)
import Json.Decode.Pipeline as JP
import String
type alias Item =
{ id : Int
, name : String
, desc : Maybe String
}
main =
Decode.decodeString (Decode.list itemDecoder) payload
|> toString
|> String.append "JSON "
|> text
itemDecoder : Decoder Item
itemDecoder =
JP.decode Item
|> JP.required "id" Decode.int
|> JP.required "name" Decode.string
|> JP.optional "desc" (Decode.map Just Decode.string) Nothing