1

有没有办法解码任意json(例如:我们在编译时不知道密钥)?

比如我需要解析下面的json:

{ 
    "Foo": [
        "Value 1",
        "Value 2"
    ],
    "Bar": [
        "Bar Value 1"
    ],
    "Baz": []
}

其中键的名称和数量在编译时是未知的,并且可能会根据 GET 请求而改变。目标基本上是将其解码为一种Map String (Array String)类型

有没有办法使用 purescript-argonaut 做到这一点?

4

2 回答 2

1

Map实例EncodeJSON会生成一个元组数组,你可以手动构造一个 Map 并查看编码后的 json。

let v = Map.fromFoldable [ Tuple "Foo" ["Value1", "Value2"] ]
traceM $ encodeJson v

输出应该是[ [ 'Foo', [ 'Value1', 'Value2' ] ] ].

要做到相反,您需要将对象转换为元组数组,Object.entries可以帮助您。

一个例子

// Main.js
var obj = {
  foo: ["a", "b"],
  bar: ["c", "d"]
};

exports.tuples = Object.entries(obj);

exports.jsonString = JSON.stringify(exports.tuples);
-- Main.purs
module Main where

import Prelude

import Data.Argonaut.Core (Json)
import Data.Argonaut.Decode (decodeJson)
import Data.Argonaut.Parser (jsonParser)
import Data.Either (Either)
import Data.Map (Map)
import Debug.Trace (traceM)
import Effect (Effect)
import Effect.Console (log)

foreign import tuples :: Json
foreign import jsonString :: String

main :: Effect Unit
main = do
  let
    a = (decodeJson tuples) :: Either String (Map String (Array String))
    b = (decodeJson =<< jsonParser jsonString) :: Either String (Map String (Array String))
  traceM a
  traceM b
  traceM $ a == b
于 2019-06-11T03:55:16.263 回答
0

您可以完全编写自己的代码,首先将字符串解析为Jsonvia jsonParser,然后使用Argonaut 提供的各种组合器检查生成的数据结构。

但我认为,最快和最简单的方法是Foreign.Object (Array String)先将其解析为,然后转换为您需要的任何内容,例如Map String (Array String)

import Data.Argonaut (decodeJson, jsonParser)
import Data.Either (Either)
import Data.Map as Map
import Foreign.Object as F

decodeAsMap :: String -> Either _ (Map.Map String (Array String))
decodeAsMap str = do
    json <- jsonParser str
    obj <- decodeJson json
    pure $ Map.fromFoldable $ (F.toUnfoldable obj :: Array _)
于 2019-06-11T20:58:47.617 回答