首页 > 解决方案 > 使用 Elm Json.Decode 将 vales 从父记录移动到子记录

问题描述

我正在编写一个 elm json 解码器,并希望将一个值从“父”记录移动到“子”记录。

在此示例中,我想将beta键/值移动到Bar类型中。

我传入的 JSON

{ "alpha": 1,
  "beta: 2,
  "bar": {
    "gamma": 3 
  }
}

我的类型

type alias Foo =
  { alpha : Int
  , bar : Bar 
  }

type alias Bar =
  { beta : Int 
  , gamma : Int 
  }

我怎样才能在解码器中做到这一点?我觉得我想将解码器传递betafooDecode. 但这显然是不对的……

fooDecode =
    decode Foo
        |> required "alpha" Json.Decode.int
        |> required "bar" barDecode (Json.Decode.at "beta" Json.Decode.int)

barDecode betaDecoder =
    decode Bar
        |> betaDecoder
        |> required "gamma" Json.Decode.int

注意:我的实际用例有一个子列表,但希望我能用指针解决这个问题。我正在使用 Decode.Pipeline 因为它是一个大型 JSON 对象

标签: elm

解决方案


您可以使用Json.Decode.andThen此处进行解析"beta",然后将其传递给管道barDecodeJson.Decode.Pipeline.custom使其与管道一起使用:

fooDecode : Decoder Foo
fooDecode =
    decode Foo
        |> required "alpha" Json.Decode.int
        |> custom
            (Json.Decode.field "beta" Json.Decode.int
                |> Json.Decode.andThen (\beta -> Json.Decode.field "bar" (barDecode beta))
            )


barDecode : Int -> Decoder Bar
barDecode beta =
    decode Bar
        |> hardcoded beta
        |> required "gamma" Json.Decode.int

有了这个变化,

main : Html msg
main =
    Html.text <| toString <| decodeString fooDecode <| """
{ "alpha": 1,
  "beta": 2,
  "bar": {
    "gamma": 3
  }
}
    """

印刷:

Ok { alpha = 1, bar = { beta = 2, gamma = 3 } }

推荐阅读