{
"RuntimeSources": {
"flask-webapp": {
"eb-flask1.3": {
"s3url": ""
}
}
},
"DeploymentId": 4,
"Serial": 4
}
有這樣一個json檔, 我現在我需要提取出flask-webapp
這個key的name,即flask-webapp
這個字串本身,我應該如何使用呢?使用Object.keys()的話我得到的是RuntimeSource,DeploymentId和Serial這三個key。
感覺自己描述的有些複雜,問題提煉一下就是:如何提取這個json檔案的第一個key-value中的下一層key-value中的key(好像說的更複雜了。希望能看懂)
用python或javascript實作都可以
漂亮男人2017-06-12 09:24:48
var o = {
"RuntimeSources": {
"flask-webapp": {
"eb-flask1.3": {
"s3url": ""
}
}
},
"DeploymentId": 4,
"Serial": 4
}
這是需要處理的數據,題主的問題應該可以看成下面問題的真子集
(問題是只要取得 "flask-webapp"
)
從物件抽離出該物件的全部鍵名,並構成一個陣列
這個過程 暫且稱之為 鋪平 flat
, 我這裡也實現了這個函數 用於取得這個解。
flat(o);
// =>
// ["RuntimeSources", "flask-webapp", "eb-flask1.3", "s3url", "DeploymentId", "Serial"]
Object.keys
能取得可列舉的第一層物件屬性鍵名
利用這樣的特性來寫遞歸函數:
var flat = o => {
// 当层键名
if (typeof o !== 'object') return [];
var keys = Object.keys(o);
return keys.reduce((acc, cur) => {
return acc.concat( flat(o[cur]) );
}, keys);
}
var log = (item, idx) => {
console.group(`第 ${idx + 1} 个元素`)
console.log('值:', item);
console.groupEnd();
}
flat(o).forEach(log);
特別地 你需要 flask-webapp
這個鍵名:
var res = flat(o).filter(e => e === 'flask-webapp');
console.log(res);
// =>
// ["flask-webapp"]
JSON.stringify
可以把物件轉換成 JSON字串
例如JSON.stringify(o)
可以得到結果"{"RuntimeSources":{"flask-webapp":{"eb-flask1.3":{"s3url":""}}},"DeploymentId ":4,"Serial":4}"
繼續觀察可以發現:
在
JSON
中,:
前的是鍵名
把 JSON 的元素構成一個數組,再把 冒號
前的挑出來就可以了。
工具函數
// 把在 str 中的 willBeReplaced 替换为 toPlace
var replaceAll = (str, willBeReplaced, toPlace) => {
return str.split(willBeReplaced).join(toPlace)
}
// 把在 str 的全部 willBeCut 替换成 ''
var cut = (str, willBeCut) => {
return replaceAll(str, willBeCut, '');
}
flat
的實作
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, '"', ''));
}
上面的意思是:
{
}
:
,
的前後補了空格對應代碼
// o 是待处理对象
let str = JSON.stringify(o);
var A = ['{', '}', ':', ','].reduce((acc, e) => {
// 把 e 的两侧都补上一个空格
return replaceAll(acc, e, ` ${e} `);
}, str)
結果是這樣的:
原來的 str 從
"{"RuntimeSources":{"flask-webapp":{"eb-flask1.3":{"s3url":""}}},"DeploymentId":4,"Serial":4}"
經過處理後 變成
" { "RuntimeSources" : { "flask-webapp" : { "eb-flask1.3" : { "s3url" : "" } } } , "DeploymentId" : 4 , "Serial" : 4 } "
得到一個中間結果 A
這裡要處理 A
對應碼:
var B = ['{', '}', ':', ','].reduce((acc, e) => {
return replaceAll(acc, e, ` ${e} `);
}, str).split(' ').filter(e => e !== "")
把 A
轉成中間數組 B
: (從字串變成數組)
觀察 B
可以得到一個結論
在
JSON
中,:
前的是鍵名
據此寫出 最後的reduce:把 冒號
前的元素收集起來 得到結果
世界只因有你2017-06-12 09:24:48
var 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} 执行四次
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]))
}
}
}
}
執行到最後應該會拋出錯誤 Cannot convert undefined or null to object,這個沒事兒
PHP中文网2017-06-12 09:24:48
如果是要用python實現的話,dict是一種散列表結構,就是說數據輸入後按特徵已經被散列了,有自己的順序
如果你可以指定key的名字倒還可以獲取,如果不能指定key的名字,那就做不到
data = {
"RuntimeSources": {
"flask-webapp": {
"eb-flask1.3": {
"s3url": ""
}
}
},
"DeploymentId": 4,
"Serial": 4
}
print data['RuntimeSources']['flask-webapp']
print data['RuntimeSources'].values()[0]
世界只因有你2017-06-12 09:24:48
python 預設字典是無序的,但是可以用 OrderedDict 有序字典來實作。
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)