如何讀取 JSON 裡巢狀的深層資料?我這兒有各語言通用方案

wanyaxing發表於2018-08-20

前言

使用JSON格式進行多個端特別是前後端之間通訊已成為主流方案之一, PHP、java、objectC、JavaScript 這幾種語言是我所在團隊接觸比較多的主要開發語言。

有一個問題

有時候,很多時候,從介面給出的資料會存在資料巢狀現象,比如在一款記賬軟體中,一條付款計劃的資料會同時攜帶計劃所在合同的資料,而合同資料裡又會攜帶合同對應客戶的資料。

如何讀取 JSON 裡巢狀的深層資料?我這兒有各語言通用方案

我們當然可以通過逐層取值的傳統方式,去取出最終的值。

然而,有一個問題,許多時候,這些資料並不一定總是存在,比如有些合同資料並沒有簽訂客戶的存在,這時候你如果不在程式碼裡做 null 值的判斷,應用程式也許就直接崩了。

此處只討論存在多重巢狀的資料提取問題,如果你的專案里約定禁止資料巢狀,那就是另一件事了。

需要一個通用的解決方案

這個問題,在各開發語言裡都會存在,所以我們團隊在討論之後,決定一起做一個通用的方案來解決。

笨辦法

核心思路很簡單,我們提出了 path (路徑)的概念,比如上文中提到的從付款計劃裡取合同客戶名稱的情況,如果用路徑來定位,用 > 作為分隔符,這個客戶名稱的定位路徑就是 results>pactUUIDLocal>customerUUIDLocal>name

那麼,我們只要封裝出一個根據路徑取值的通用方法來,取值時,只管呼叫方法去取各路徑的值,如果不存在值就返回 null,這個問題不就解決了嘛。

是的,本文的核心思路就是如此。

陣列怎麼辦

將陣列看成key為下標的字典,即可。

HaoResult .php .m .java .js

經過不斷調整,我們定義了一個 HaoResult 類,用來例項化 json 物件,並實現了 HaoResult.find(path) 這個核心方法。

各語言實現方式的程式碼如下, 供參考,分別來自 HaoConnectHaoAdmin

HaoResult.php

HaoResult.m

HaoResult.java

haoresult.js

其實,在各語言裡都存在著類似的處理方案,本文最重要的意義是提出並實現了在各個端邏輯統一的資料處理方法

還可以做的更好

為什麼我們要將路徑約定為一個字串,而不是一串引數或者一個陣列呢?因為這裡還有一個更讚的升級功能:根據模糊路徑搜尋資料

比如,有一個介面返回了文章的點贊列表,如果要取第一個使用者名稱,可以用 HaoResult.find("results>0>username") 來定位路徑提取資料。

那麼,如果要取出所有的使用者名稱呢?

我們實現了 search 方法,可以用 HaoResult.search("results>\d+>username") 來獲得使用者名稱組成的陣列,酷吧:)

簡單的說,search 方法的引數是一個正則字串,使用該正則去在所有的路徑中嘗試匹配,然後再將匹配到路徑的資料都取出來。

後語

本想在本文中列出更多的程式碼來作補充說明,然而仔細想想,本文最重要的就是一個解決問題的思路方向,又何必堆疊更多的程式碼文字呢。

文中提供了各語言的實現程式碼範例,僅供參考,也可略作修改後即可使用。

本文是 HaoObject.js 系列的前置文章,至於如何在 Vue 下將資料也玩出點花樣兒來,敬請期待。

如何讀取 JSON 裡巢狀的深層資料?我這兒有各語言通用方案

原文來自阿星的部落格: wanyaxing.com/blog/201808…

相關文章