javascript - 關(guān)于json中獲取多個(gè)key-value對(duì)中多層嵌套key的name
問(wèn)題描述
{ 'RuntimeSources': { 'flask-webapp': { 'eb-flask1.3': {'s3url': '' } } }, 'DeploymentId': 4, 'Serial': 4}
有這樣一個(gè)json文件, 我現(xiàn)在我需要提取出flask-webapp這個(gè)key的name,即flask-webapp這個(gè)字符串本身,我應(yīng)該如何使用呢?使用Object.keys()的話我得到的是RuntimeSource,DeploymentId和Serial這三個(gè)key。感覺(jué)自己描述的有些復(fù)雜,問(wèn)題提煉一下就是:如何提取這個(gè)json文件的第一個(gè)key-value中的下一層key-value中的key(好像說(shuō)的更復(fù)雜了。。希望能看懂吧)用python或者javascript實(shí)現(xiàn)都可以
問(wèn)題解答
回答1:function getFirstKeyInLevel(json, level) { var levelNow = 0; var key; var obj = json; do {key = Object.keys(obj)[0];levelNow++;obj = obj[key]; } while (key && levelNow < level); return key;}var json = { ’RuntimeSources’: {’flask-webapp’: { ’eb-flask1.3’: {’s3url’: ’’ }} }, ’DeploymentId’: 4, ’Serial’: 4};console.log(getFirstKeyInLevel(json, 1)); // RuntimeSourcesconsole.log(getFirstKeyInLevel(json, 2)); // flask-webappconsole.log(getFirstKeyInLevel(json, 3)); // eb-flask1.3console.log(getFirstKeyInLevel(json, 4)); // s3urlconsole.log(getFirstKeyInLevel(json, 5)); // undefined回答2:
var o = { 'RuntimeSources': { 'flask-webapp': { 'eb-flask1.3': {'s3url': '' } } }, 'DeploymentId': 4, 'Serial': 4}
這是需要處理的數(shù)據(jù),題主的問(wèn)題應(yīng)該可以看成下面問(wèn)題的一個(gè)真子集 (問(wèn)題是只要取得 'flask-webapp')
從對(duì)象里抽離出該對(duì)象的全部鍵名,并構(gòu)成一個(gè)數(shù)組
這個(gè)過(guò)程 暫且稱之為 鋪平 flat, 我這里也實(shí)現(xiàn)了這個(gè)函數(shù) 用于取得這個(gè)解。
flat(o); // => // ['RuntimeSources', 'flask-webapp', 'eb-flask1.3', 's3url', 'DeploymentId', 'Serial']利用 Object.keys 解決問(wèn)題
Object.keys 能獲得可枚舉的第一層對(duì)象屬性鍵名
利用這樣的特性編寫(xiě)遞歸函數(shù):
var flat = o => { // 當(dāng)層鍵名 if (typeof o !== ’object’) return []; var keys = Object.keys(o); return keys.reduce((acc, cur) => {return acc.concat( flat(o[cur]) ); }, keys); }ScreenShot
var log = (item, idx) => { console.group(`第 ${idx + 1} 個(gè)元素`) console.log(’值:’, item); console.groupEnd(); }flat(o).forEach(log);
特別地 你需要 flask-webapp 這個(gè)鍵名:
var res = flat(o).filter(e => e === ’flask-webapp’); console.log(res); // => // ['flask-webapp'] 利用 JSON.stringify 解決問(wèn)題
JSON.stringify 可以把對(duì)象轉(zhuǎn)化成 JSON字符串
比如 JSON.stringify(o) 可以得到結(jié)果'{'RuntimeSources':{'flask-webapp':{'eb-flask1.3':{'s3url':''}}},'DeploymentId':4,'Serial':4}'
繼續(xù)觀察可以發(fā)現(xiàn):
在 JSON 中, : 前的是鍵名
把 JSON 的元素構(gòu)成一個(gè)數(shù)組,再把 冒號(hào) 前的挑出來(lái)就可以了。
工具函數(shù)
// 把在 str 中的 willBeReplaced 替換為 toPlacevar replaceAll = (str, willBeReplaced, toPlace) => { return str.split(willBeReplaced).join(toPlace)}// 把在 str 的全部 willBeCut 替換成 ’’var cut = (str, willBeCut) => { return replaceAll(str, willBeCut, ’’); }
flat 的實(shí)現(xiàn)
var flat = o => { var str = JSON.stringify(o); return [’{’, ’}’, ’:’, ’,’].reduce((acc, e) => {return replaceAll(acc, e, ` ${e} `); }, str).split(’ ’).filter(e => e !== '').reduce((acc, cur, idx, its) => {if (cur === ’:’){ acc.push(its[idx - 1]); }return acc; }, []).map(e => cut(e, ’'’, ’’)); }
上面的意思是:
第一個(gè) reduce 給 { } : , 的前后補(bǔ)了空格對(duì)應(yīng)代碼
// o 是待處理對(duì)象 let str = JSON.stringify(o); var A = [’{’, ’}’, ’:’, ’,’].reduce((acc, e) => { // 把 e 的兩側(cè)都補(bǔ)上一個(gè)空格 return replaceAll(acc, e, ` ${e} `); }, str)
結(jié)果是這樣的:
原來(lái)的 str 從
'{'RuntimeSources':{'flask-webapp':{'eb-flask1.3':{'s3url':''}}},'DeploymentId':4,'Serial':4}'
經(jīng)過(guò)處理后 變成
' { 'RuntimeSources' : { 'flask-webapp' : { 'eb-flask1.3' : { 's3url' : '' } } } , 'DeploymentId' : 4 , 'Serial' : 4 } '
得到一個(gè)中間結(jié)果 A
Next這里要處理 A
對(duì)應(yīng)代碼:
var B = [’{’, ’}’, ’:’, ’,’].reduce((acc, e) => { return replaceAll(acc, e, ` ${e} `); }, str).split(’ ’).filter(e => e !== '')
把 A 轉(zhuǎn)成中間數(shù)組 B: (從字符串變成數(shù)組)
觀察 B 可以得到一個(gè)結(jié)論
在 JSON 中, : 前的是鍵名
據(jù)此寫(xiě)出 最后的reduce:把 冒號(hào) 前的元素收集起來(lái) 得到結(jié)果
ScreenShotvar object= { 'RuntimeSources': { 'flask-webapp': { 'eb-flask1.3': {'s3url': '' } } }, 'DeploymentId': 4, 'Serial': 4} for(i in object){console.log(Object.keys(object[i]));// console.log(object[i]);//Object {flask-webapp: Object} 執(zhí)行四次for(k in object[i]){ console.log(Object.keys(object[i][k])); // console.log(object[i][k]);//Object {eb-flask1.3: Object} for(s in object[i][k]){console.log(Object.keys(object[i][k][s]));//console.log(object[i][k][s])//Object {s3url: ''}for( f in object[i][k][s]){ console.log(Object.keys(object[i][k][f]))} }} }
執(zhí)行到最后應(yīng)該會(huì)拋出錯(cuò)誤 Cannot convert undefined or null to object,這個(gè)沒(méi)事兒
回答4:如果是要用python實(shí)現(xiàn)的話,dict是一種散列表結(jié)構(gòu),就是說(shuō)數(shù)據(jù)輸入后按特征已經(jīng)被散列了,有自己的順序如果你可以指定key的名字倒還可以獲取,如果不能指定key的名字,那就做不到
data = { 'RuntimeSources': { 'flask-webapp': { 'eb-flask1.3': {'s3url': '' } } }, 'DeploymentId': 4, 'Serial': 4}print data[’RuntimeSources’][’flask-webapp’]print data[’RuntimeSources’].values()[0]回答5:
python 默認(rèn)字典是無(wú)序的,但是可以用 OrderedDict 有序字典來(lái)實(shí)現(xiàn)。
def level_keys(order_dict, level): _level = 1 if level == _level:return order_dict.get(order_dict.keys()[0]).keys() else:return level_keys(order_dict.get(order_dict.keys()[0]), level=level - 1)def main(level=1): from collections import OrderedDict import json dict_str = '''{ 'RuntimeSources': { 'flask-webapp': { 'eb-flask1.3': {'s3url': '' } } }, 'DeploymentId': 4, 'Serial': 4}''' order_dict = json.loads(s=dict_str, object_pairs_hook=OrderedDict) print(level_keys(order_dict, level))if __name__ == ’__main__’: main(3)回答6:
var json = JSON.parse(’{ 'RuntimeSources': { 'flask-webapp': { 'eb-flask1.3': {'s3url': '' } } }, 'DeploymentId': 4, 'Serial': 4}’);for (t in json) { console.log(t); }var test = Object.keys(json);console.log(test[0]);
相關(guān)文章:
1. javascript - vue-router怎么不能實(shí)現(xiàn)跳轉(zhuǎn)呢2. npm鏡像站全新上線3. 老哥們求助啊4. css3 - 請(qǐng)問(wèn)一下在移動(dòng)端CSS布局布局中通常需要用到哪些元素,屬性?5. mySql排序,序號(hào)6. html5 - angularjs中外部模版加載無(wú)法使用7. django - 后臺(tái)返回的json數(shù)據(jù)經(jīng)過(guò)Base64加密,獲取時(shí)用python如何解密~!8. node.js - node 客戶端socket一直報(bào)錯(cuò)Error: read ECONNRESET,用php的socket沒(méi)問(wèn)題哈。。9. tp6表單令牌10. 我的html頁(yè)面一提交,網(wǎng)頁(yè)便顯示出了我的php代碼,求問(wèn)是什么原因?
