2017-06-07 37 views
1

數組但對如何事情榆樹解碼另一個問題......解碼JSON其中value可以是一個字符串或者不同的值

所以問題是,我需要解碼的值可以是字符串,例如

"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包)

但很明顯,它抱怨在列表和諸如此類的東西,以便對不同價值觀我被卡住了。

預先感謝您。

回答

3

你很接近,但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." 
      ) 
+0

我有一種感覺,它不會是一個班輪...... :)非常感謝 – JustMichael

相關問題