【问题标题】:purescript-argonaut: Decode arbitrary key-value jsonpurescript-argonaut:解码任意键值 json
【发布时间】:2019-06-10 21:08:14
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: json purescript argonaut


    【解决方案1】:

    EncodeJSONMap 实例会生成一个元组数组,您可以手动构造一个 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
    

    【讨论】:

      【解决方案2】:

      您完全可以编写自己的代码,首先通过jsonParser 将字符串解析为Json,然后使用various combinators provided by 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 _)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-03
        相关资源
        最近更新 更多