Elm: 将只包含一个元素的 JSON 数组解码为字符串

3
搜索了一下类似的内容,但找不到确切的问题。
我从服务器端获得了一个JSON,看起来像这样:
{ 
  "field": ["field-name"], 
  "messages":["message","message"]
}

我想做的是将它解码为 elm 记录,例如:
{ field: String, messages: List String }

然而,我在处理 field 字段时遇到了问题。我不知道如何将单个元素的 JSON 数组转换为仅包含该元素的字符串。
我不知道 Decode 是否支持这种操作,或者我最好将其解码为列表,然后只获取列表中的第一个元素。
以下是我的解码代码:
valErrorDecoder : Decode.Decoder ValError
valErrorDecoder =
decode ValError
    |> required "field" (Decode.list Decode.string)
    |> required "messages" (Decode.list Decode.string)

谢谢任何帮助!

我遇到了相同的问题。尝试了两种解决方案。但是,如果Json中出现空列表,则需要使用“Maybe”。Decode.index将无法捕获失败。 - su hui
2个回答

11

试试Decode.index,那应该可以解决问题。

valErrorDecoder : Decode.Decoder ValError
valErrorDecoder =
decode ValError
    |> required "field" (Decode.index 0 Decode.string)
    |> required "messages" (Decode.list Decode.string)

1
谢谢!一个同事建议使用Decode.map,但这个看起来更简单一些。 - m4v15

4

在评论中,您提到有同事建议使用Decode.map。如果您感到好奇,以下是这种(更复杂的)解决方案可能会像:

firstElementDecoder : Decode.Decoder a -> Decode.Decoder a
firstElementDecoder baseDecoder = Decode.list baseDecoder
 |> Decode.map List.head
 |> Decode.andThen (Maybe.map Decode.succeed >> Maybe.withDefault (Decode.fail "Empty list"))

这里正在发生什么?我们首先对一系列字符串进行解码,然后将 List.head 函数映射到该列表上,得到一个 Decoder (Maybe String)。该函数...
Maybe.map Decode.succeed 
  >> Maybe.withDefault (Decode.fail "Empty list")

将一个 Maybe 转换成一个解码器,如果成功(带有 maybe 的值),则解码器会成功;如果失败,则会返回“空列表”错误消息。我们将此函数用作 Decode.andThen 的参数,该函数执行以下操作:
  1. 将列表解码器中的 Maybe 传递给上述函数,获取 Decode.succeedDecode.fail
  2. 运行返回的解码器,成功或失败并返回相应的值。
所以,是的,Decode.index 0 更容易!但也许看到更长的解决方案也会有趣 :-)

感谢您添加这个额外的答案。它最终使我能够构建一个仅在输入为单个字符字符串时成功的解码器Char。它还展示了如何将任意额外的验证插入到解码器链中。 - Mark Farmiloe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接