榆树:将Json解码为简单的记录结构

时间:2015-11-20 07:55:42

标签: elm

努力寻找完成解码器的正确方法。我从表格

的数据开始
[{_id:'interests', [{obj1}, {obj1}]}
,{_id:'countries', [{obj2}, {...}]} 
,{_id:'sections', [{obj3}, {...}]}]

我想到Decoder Summary

type alias Summary =
    { sections : List Section
    , interests : List Interest
    , countries : List Country
    }

到目前为止,我能够做到的最好的就是这种输出:

[ Interests (List Interest), Countries (List Country), Sections (List Section)]

但仍然需要一些相当脆弱的模式匹配(依赖于数组的一致顺序,因此0.16 非常有问题)。为此,我使用

summaryItemDecoder : String -> Decoder SummaryInfo
summaryItemDecoder item =
    let dec =
        case item of
            "sections" -> Json.map Sections sectionsDecoder
            "interests" -> Json.map Interests interestsDecoder
            "countries" -> Json.map Countries countriesDecoder
    in ("data" := dec)

listSummaryDecoder : Decoder (List SummaryInfo)
listSummaryDecoder =
    ("_id" := string) `Json.andThen` summaryItemDecoder
    |> list

完整代码here。感谢一些最后的提示

2 个答案:

答案 0 :(得分:2)

我不确定你能做得更好;您试图解析一种可以表达您在类型中无法表达的内容的格式,因此您唯一的选择就是失败。

为了满足模式匹配的神,可能会在otherwise解码器中删除一个fail子句? (http://package.elm-lang.org/packages/elm-lang/core/3.0.0/Json-Decode#fail

答案 1 :(得分:0)

您可以将信息列表折叠为摘要。

type Interest = Interest
type Section = Section
type Country = Contry

type Info =  Interests (List Interest) | Countries (List Country) | Sections (List Section) 


type alias Summary =
    { sections : List Section
    , interests : List Interest
    , countries : List Country
    }

emptySummary : Summary
emptySummary = 
    { sections = []
    , interests = []
    , countries = []
    }


toSummary : List Info -> Summary
toSummary xs = 
  let 
    insert info sum =
      case info of 
        Sections ss -> { sum | sections = ss }
        Interests is -> { sum | interests = is }
        Countries cs -> { sum | countries = cs } 

  in
    List.foldl insert emptySummary xs

infoList : List Info
infoList = []

summary = toSummary infoList