【Python】关于json中获取多个key-value对中多层嵌套key的name
{"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实现都可以
回答
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)); // RuntimeSources
console.log(getFirstKeyInLevel(json, 2)); // flask-webapp
console.log(getFirstKeyInLevel(json, 3)); // eb-flask1.3
console.log(getFirstKeyInLevel(json, 4)); // s3url
console.log(getFirstKeyInLevel(json, 5)); // undefined
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 解决问题
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);
}
ScreenShot
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.stringify
可以把对象转化成 JSON字符串
比如 JSON.stringify(o)
可以得到结果"{"RuntimeSources":{"flask-webapp":{"eb-flask1.3":{"s3url":""}}},"DeploymentId":4,"Serial":4}"
继续观察可以发现:
在
JSON
中,:
前的是键名
把 JSON 的元素构成一个数组,再把 冒号
前的挑出来就可以了。
工具函数
// 把在 str 中的 willBeReplaced 替换为 toPlacevar 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, '"', ''));
}
上面的意思是:
第一个 reduce 给 {
}
:
,
的前后补了空格
对应代码
// 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
Next
这里要处理 A
对应代码:
var B = ['{', '}', ':', ','].reduce((acc, e) => { return replaceAll(acc, e, ` ${e} `);
}, str).split(' ').filter(e => e !== "")
把 A
转成中间数组 B
: (从字符串变成数组)
最后一个 reduce 得到结果
观察 B
可以得到一个结论
在
JSON
中,:
前的是键名
据此写出 最后的reduce:把 冒号
前的元素收集起来 得到结果
ScreenShot
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,这个没事儿
如果是要用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]
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)
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]);
以上是 【Python】关于json中获取多个key-value对中多层嵌套key的name 的全部内容, 来源链接: utcz.com/a/80577.html