2017-03-09 5 views
3

Meine JSON sieht wie folgt ausDecode ein JSON Tupels Elm Tupel

{ "resp": 
    [ [1, "things"] 
    , [2, "more things"] 
    , [3, "even more things"] 
    ] 
} 

das Problem ist, dass ich die JSON Tupeln in Elm Tupeln nicht analysieren kann:

decodeThings : Decoder (List (Int, String)) 
decodeThings = field "resp" <| list <| map2 (,) int string 

Es kompiliert, aber wenn lief, wirft es

BadPayload "Expecting an Int at _.resp[2] but instead got [3, \"even more things\"] 

Aus irgendeinem Grunde liest es [3, "even more things"] als nur eine Sache und nicht als Tupel im JSON-Format.
Wie kann ich meine JSON in eine List (Int, String) analysieren?

+1

Ihre JSON nicht Ihre Beschreibung passen - '[1, "Dinge"]' a JSON ist * array * und kein JSON * Objekt * (was ich erwarten würde, seit Sie JSON-Tupel erwähnt haben). Versuchen Sie stattdessen '{1, dings}}' oder ändern Sie Ihren Elm-Decoder, um eine Liste von Listen zu akzeptieren. –

Antwort

8

Sie benötigen einen Decoder, der ein Javascript-Array der Größe zwei in ein Elm-Tupel der Größe zwei verwandelt. Hier ist ein Beispiel Decoder:

arrayAsTuple2 : Decoder a -> Decoder b -> Decoder (a, b) 
arrayAsTuple2 a b = 
    index 0 a 
     |> andThen (\aVal -> index 1 b 
     |> andThen (\bVal -> Json.Decode.succeed (aVal, bVal))) 

Anschließend können Sie Ihr ursprüngliches Beispiel wie folgt ändern:

decodeThings : Decoder (List (Int, String)) 
decodeThings = field "resp" <| list <| arrayAsTuple2 int string 

(Beachten Sie, dass mein Beispiel Decoder nicht ausfällt, wenn es mehr als zwei Elemente, aber es sollten Sie in die richtige Richtung gehen)

+0

Arbeitete wie ein Charme. Warum gibt es keine Standardimplementierung für Tupel, wenn sie als Listen dargestellt werden? – Patrick

+2

Es gab 'tupleN' Decoder, die in nativem Javascript implementiert wurden, aber diese wurden [entfernt] (https://github.com/elm-lang/core/commit/3b999526e08ac517c0223a55c78cb13e752be3f8) und die empfohlene Handhabung ist [index ] (https://github.com/elm-lang/core/commit/c341774223da6ad30eb67d1628cbea68c6fcd27e). Ich bin mir nicht sicher, was die Argumentation genau war. –

3

Simplest ist

map2 (,) (index 0 string) (index 1 string) 

und dann, wie Sie beachten, für die Liste

list <| map2 (,) (index 0 string) (index 1 string)