1

我正在尝试解码具有该类型的 JSON 数组Js.Json.tarray(Js.Json.t)显然不是)。调用Js.log(jsonList)显示它是一个数组,但我不确定如何映射数组中的元素以对其进行解码。

到目前为止,我有:

let json_to_list = response => {
    switch (response |> Js.Json.decodeObject) {
        | None => {
            Js.log("Decoding JSON failed!!")
            None
        }
        | Some(jsonObject) => {
            switch (jsonObject -> Js.Dict.get("list")) {
                | None => {
                    Js.log("JSON didn't have a 'list' key/value.")
                    None
                }
                | Some(jsonList) => {
                    jsonList
                    |> Js.List.map(
                            /*  compiler is expecting an uncurried function */
                            record => {
                            switch (record->Js.Dict.get("session-id") { /* ... */ }
                        }
                    )
                }
            }
        }
    }
};

编译器需要一个非柯里化函数,我不知道如何提供。

编辑

我想我更接近了,但我正在This has type: array(unit) Somewhere wanted: unit上线(下)value |> Array.map(Js.log)

let json_to_list = response => {
    Js.log("Decoding JSON")
    switch (response |> Js.Json.decodeObject) {
        | None => {
            Js.log("Decoding JSON failed!!")
            None
        }
        | Some(jsonObject) => {
            switch (jsonObject -> Js.Dict.get("list")) {
                | None => {
                    Js.log("JSON didn't have a 'list' key/value.")
                    None
                }
                | Some(jsonArray) => switch (Js.Json.decodeArray(jsonArray)) {
                    | None => {
                        Js.log("JSON Object wasn't an array.")
                        None
                    }
                    | Some(value) => {
                        Js.log("Value length: " ++ string_of_int(value|>Js.Array.length))
                        value |> Array.map(Js.log)
                        Some(value)
                    }
                }
            }
        }
    }
};
4

1 回答 1

2

有几种方法可以做到这一点,具体取决于您在编译时对数据的了解以及您实际需要什么。

如果您确切地知道它是什么,并且没有机会收到其他任何东西,您可以将其转换为您想要的类型,而无需在运行时进行任何检查:

external toMyType: Js.Json.t => array(something) = "%identity"

let myData = toMyType(json)

如果您直到运行时才知道数据的形状,您可以使用Js.Json.classify

let decodeArrayItem = ...

let myData : array(something) =
  switch Js.Json.classify(json) {
  | Js.Json.JSONArray(array) => Array.map(decodeArrayItem, array)
  | _ => []
  }
}

或者,如果您可以得到任何东西,但您只关心数组,您可以将Js.Json.,decodeArray其用作速记,它会返回一个option您可以进一步处理的内容:

let decodeArrayItem = ...

let maybeData : option(array(something)) =
  Js.Json.decodeArray(json)
  |> Option.map(Array.map(decodeArrayItem))

最后,对于大多数情况,我推荐的选项是使用第三方 JSON 解码器库之一,它往往是为组合而设计的,因此更方便解码大型数据结构。例如,使用@glennsll/bs-json(这里显然没有偏见):

module Decode = {
  let arrayItem = ...

  let myData =
    Json.Decode.array(arrayItem)
}

let myData =
  try Decode.myData(json) catch {
  | Js.Json.DecodeError(_) => []
  }

编辑:至于你得到的实际错误,你可以通过使用稍微不同的语法将一个 curried anonymus 函数变成一个 uncurried 函数:

let curried = record => ...
let uncurried = (. record) => ...
于 2020-12-16T13:17:25.377 回答