解码 JSON 其中值可以是字符串或不同值的数组
Decode JSON where value can be a string or an array of different values
关于如何使用 Elm 解码的另一个问题...
所以问题是我需要解码一个可以是字符串的值,例如
"price_unknown"
或者它可以是 2 个元素的数组,其中第一个是字符串,第二个是浮点数:
["price", 50.5]
对于最终值,我有一个类型:
type Something
= PriceUnknown
= Price Float
我需要将 json 响应的值转换成其中的值。
我尝试在以下几行之间使用一些东西:
decode MyString
|> required "other_value" Json.Decode.string
|> required "price" JD.oneOf [JD.string, JD.list (JD.oneOf [JD.string, JD.float])] |> JD.map mapper
(我这里用的是json_decode_pipeline
包)
但显然它抱怨列表中的不同值等等,所以我被卡住了。
提前致谢。
你很接近,但是 oneOf
中的所有 Decoder
必须具有相同的类型。此外,解构混合列表可能会很痛苦。这使用 elm-community/json-extra 使手动解码步骤更容易。
myDecoder : Decoder SomethingElse
myDecoder =
decode MyString
|> required "other_value" Json.Decode.string
|> required "price" priceDecoder
priceDecoder : Decoder Something
priceDecoder =
JD.oneOf
[ priceUnknownDecoder
, priceKnownDecoder
]
priceUnknownDecoder : Decoder Something
priceUnknownDecoder =
JD.string
|> JD.andThen
(\string ->
if string == "price_unknown" then
JD.succeed PriceUnknown
else
JD.fail "Invalid unknown price string."
)
priceKnownDecoder : Decoder Something
priceKnownDecoder =
listTupleDecoder
JD.string
JD.float
|> JD.andThen
(\(tag, price) ->
if tag == "price" then
JD.succeed (Price price)
else
JD.fail "Invalid tag string."
)
listTupleDecoder : Decoder a -> Decoder b -> Decoder (a, b)
listTupleDecoder firstD secondD =
JD.list JD.value
|> JD.andThen
(\values ->
case values of
[first, second] ->
Result.map2
(,)
JD.decodeValue firstD first
JD.decodeValue secondD second
|> JD.Extra.fromResult
_ ->
JD.fail "There aren't two values in the list."
)
关于如何使用 Elm 解码的另一个问题...
所以问题是我需要解码一个可以是字符串的值,例如
"price_unknown"
或者它可以是 2 个元素的数组,其中第一个是字符串,第二个是浮点数:
["price", 50.5]
对于最终值,我有一个类型:
type Something
= PriceUnknown
= Price Float
我需要将 json 响应的值转换成其中的值。
我尝试在以下几行之间使用一些东西:
decode MyString
|> required "other_value" Json.Decode.string
|> required "price" JD.oneOf [JD.string, JD.list (JD.oneOf [JD.string, JD.float])] |> JD.map mapper
(我这里用的是json_decode_pipeline
包)
但显然它抱怨列表中的不同值等等,所以我被卡住了。
提前致谢。
你很接近,但是 oneOf
中的所有 Decoder
必须具有相同的类型。此外,解构混合列表可能会很痛苦。这使用 elm-community/json-extra 使手动解码步骤更容易。
myDecoder : Decoder SomethingElse
myDecoder =
decode MyString
|> required "other_value" Json.Decode.string
|> required "price" priceDecoder
priceDecoder : Decoder Something
priceDecoder =
JD.oneOf
[ priceUnknownDecoder
, priceKnownDecoder
]
priceUnknownDecoder : Decoder Something
priceUnknownDecoder =
JD.string
|> JD.andThen
(\string ->
if string == "price_unknown" then
JD.succeed PriceUnknown
else
JD.fail "Invalid unknown price string."
)
priceKnownDecoder : Decoder Something
priceKnownDecoder =
listTupleDecoder
JD.string
JD.float
|> JD.andThen
(\(tag, price) ->
if tag == "price" then
JD.succeed (Price price)
else
JD.fail "Invalid tag string."
)
listTupleDecoder : Decoder a -> Decoder b -> Decoder (a, b)
listTupleDecoder firstD secondD =
JD.list JD.value
|> JD.andThen
(\values ->
case values of
[first, second] ->
Result.map2
(,)
JD.decodeValue firstD first
JD.decodeValue secondD second
|> JD.Extra.fromResult
_ ->
JD.fail "There aren't two values in the list."
)