簡體   English   中英

如何迭代/映射作為數組的 Js.Json.t?

[英]How can one iterate/map over a Js.Json.t that is an array?

我正在嘗試解碼具有 Js.Json.t 類型的Js.Json.t數組(顯然不是array(Js.Json.t) )。 Js.log(jsonList)的調用表明它是一個數組,但我不確定如何對數組中的元素進行 map 以對其進行解碼。

到目前為止,我有:

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") { /* ... */ }
                        }
                    )
                }
            }
        }
    }
};

編譯器期待一個未咖喱化的 function,我不知道如何提供。

編輯

我想我更接近了,但我得到了一個This has type: array(unit) Somewhere wanted: unit on the line (below) 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)
                    }
                }
            }
        }
    }
};

有幾種方法可以做到這一點,具體取決於您在編譯時對數據的了解以及您實際需要什么。

如果您確切地知道它是什么,並且沒有機會收到其他任何東西,您可以將其轉換為您想要的類型,而無需在運行時進行任何檢查:

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)
  | _ => []
  }
}

或者,如果除了 arrays 之外,您還能得到任何東西,您可以使用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(_) => []
  }

編輯:至於你得到的實際錯誤,你可以通過使用稍微不同的語法將一個咖喱匿名 function 變成一個非咖喱匿名:

let curried = record => ...
let uncurried = (. record) => ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM