JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它基于JavaScript的对象语法,但独立于语言。深度嵌套的JSON对象是指包含多层嵌套的对象或数组结构。
递归是处理嵌套结构的经典方法,适用于未知深度的JSON结构。
function traverseJSON(obj, callback) {
if (typeof obj === 'object' && obj !== null) {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
callback(key, obj[key], obj);
traverseJSON(obj[key], callback);
}
}
}
}
// 使用示例
const nestedJSON = {
a: 1,
b: {
c: 2,
d: {
e: 3
}
},
f: [4, {g: 5}]
};
traverseJSON(nestedJSON, (key, value, parent) => {
console.log(`Key: ${key}, Value: ${JSON.stringify(value)}`);
});
对于非常深的嵌套结构,递归可能导致栈溢出,可以使用迭代方法。
function traverseJSONIterative(obj, callback) {
const stack = [{obj, path: []}];
while (stack.length > 0) {
const {obj: currentObj, path} = stack.pop();
if (typeof currentObj === 'object' && currentObj !== null) {
const keys = Object.keys(currentObj).reverse();
for (const key of keys) {
const value = currentObj[key];
const currentPath = [...path, key];
callback(key, value, currentObj, currentPath);
stack.push({obj: value, path: currentPath});
}
}
}
}
function* traverseJSONGenerator(obj, path = []) {
if (typeof obj === 'object' && obj !== null) {
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const value = obj[key];
const currentPath = [...path, key];
yield {key, value, path: currentPath};
yield* traverseJSONGenerator(value, currentPath);
}
}
}
}
// 使用示例
for (const {key, value, path} of traverseJSONGenerator(nestedJSON)) {
console.log(`Path: ${path.join('.')}, Key: ${key}, Value: ${JSON.stringify(value)}`);
}
原因:JSON对象中存在循环引用(A引用B,B又引用A)
解决方案:
function traverseJSONSafe(obj, callback, visited = new WeakSet()) {
if (typeof obj === 'object' && obj !== null) {
if (visited.has(obj)) return;
visited.add(obj);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
callback(key, obj[key], obj);
traverseJSONSafe(obj[key], callback, visited);
}
}
}
}
解决方案:明确区分对象和数组的处理方式
function traverseJSONWithArrays(obj, callback, path = []) {
if (Array.isArray(obj)) {
obj.forEach((item, index) => {
const currentPath = [...path, index];
callback(index, item, obj, currentPath);
traverseJSONWithArrays(item, callback, currentPath);
});
} else if (typeof obj === 'object' && obj !== null) {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
const currentPath = [...path, key];
callback(key, obj[key], obj, currentPath);
traverseJSONWithArrays(obj[key], callback, currentPath);
}
}
}
}
虽然这不是原生JavaScript功能,但可以使用库来实现类似XPath的查询:
// 假设已引入jsonpath库
const jsonpath = require('jsonpath');
const nestedJSON = {
a: 1,
b: {
c: 2,
d: {
e: 3
}
},
f: [4, {g: 5}]
};
// 查找所有数值
const numbers = jsonpath.query(nestedJSON, '$..*').filter(v => typeof v === 'number');
console.log(numbers); // [1, 2, 3, 4, 5]
遍历深度嵌套JSON对象是处理复杂数据结构的常见需求,选择合适的方法取决于具体的使用场景和性能要求。
没有搜到相关的文章