我有一个具有深层嵌套结构的 JSON,我想要 Javascript/Typescript 中的通用函数来删除多个深层结构。通用就像除了
categories
之外可能有任何父级可能在其键中嵌套。
下面是一个具有深度嵌套的 JSON 示例:-
const nestedObject = {
"code": {
"prev": [],
"current": null
},
"updatedAt": {
"prev": "2024-05-22T12:33:38.834Z",
"current": "2024-05-23T08:47:11.151Z"
},
"categories": {
"5": {
"prev": null,
"current": {
"id": 12,
"name": "Value-1"
}
},
"6": {
"prev": null,
"current": {
"id": 13,
"name": "Value-2"
}
},
"7": {
"prev": null,
"current": {
"id": 14,
"name": "Value-3"
}
},
"25": {
"24": {
"23": {
"22": {
"21": {
"20": {
"19": {
"18": {
"prev": null,
"current": {
"id": 25,
"name": "Value-3"
}
},
"prev": null,
"current": {
"id": 26,
"name": "Value-4"
}
},
"prev": null,
"current": {
"id": 27,
"name": "Value-5"
}
},
"prev": null,
"current": {
"id": 28,
"name": "Value-6"
}
},
"prev": null,
"current": {
"id": 29,
"name": "Value-7"
}
},
"prev": null,
"current": {
"id": 30,
"name": "Value-8"
}
},
"prev": null,
"current": {
"id": 31,
"name": "Value-9"
}
},
"prev": null,
"current": {
"id": 32,
"name": "Value-10"
}
}
}
};
在示例中,类别中有深度嵌套(即 25->24->23->22->21...)。 我想让它像categories.3和categories.4一样 以下是我希望通用函数给出的预期输出:-
const expectedOutput = {
"code": {
"prev": [],
"current": null
},
"updatedAt": {
"prev": "2024-05-22T12:33:38.834Z",
"current": "2024-05-23T08:47:11.151Z"
},
"categories": {
"5": {
"prev": null,
"current": {
"id": 12,
"name": "Value-1"
}
},
"6": {
"prev": null,
"current": {
"id": 13,
"name": "Value-2"
}
},
"7": {
"prev": null,
"current": {
"id": 14,
"name": "Value-3"
}
},
"18": {
"prev": null,
"current": {
"id": 25,
"name": "Value-3"
}
},
"19": {
"prev": null,
"current": {
"id": 26,
"name": "Value-4"
}
},
"20": {
"prev": null,
"current": {
"id": 27,
"name": "Value-5"
}
},
"21": {
"prev": null,
"current": {
"id": 28,
"name": "Value-6"
}
},
"22": {
"prev": null,
"current": {
"id": 29,
"name": "Value-7"
}
},
"23": {
"prev": null,
"current": {
"id": 30,
"name": "Value-8"
}
},
"24": {
"prev": null,
"current": {
"id": 31,
"name": "Value-9"
}
},
"25": {
"prev": null,
"current": {
"id": 32,
"name": "Value-10"
}
}
}
};
我发现了一个可以扁平化 JSON 的函数。但这并没有给我预期的输出。这是函数。
const flattenObject = (obj, prefix = '') => {
let result = {};
for (let key in obj) {
if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
const nested = flattenObject(obj[key], `${prefix}${key}.`);
result = { ...result, ...nested };
} else {
result[`${prefix}${key}`] = obj[key];
}
}
return result;
};
这是完成您所提供的 JSON 所需功能的函数:
function flattenNestedObject({ categories, ...rest }) {
return {
// copy all fields except `categories`
...rest,
// overwrite `categories` with a flattened version
categories: flattenCategories(categories)
}
}
function flattenCategories(categories) {
// iterate category keys
return Object.keys(categories)
.reduce((result, key) => {
// extract all nested categories for the given key
// and return the new accumulated result
return flattenCategory(categories[key], result, key)
}, {})
}
/**
*
* @param category category object to flatten
* @param result accumulated result, the flattened category is assigned here
* @param catKey key of the category out of which we're pulling the nested categories
* @returns accumulated result with all current nested categories flattened
*/
function flattenCategory(category, result, catKey) {
// iterate category's keys
return Object.keys(category)
.reduce((acc, key) => {
// set `catKey` with some placeholder values on the currently
// acc. result, if it isn't already set
acc[catKey] ??= { prev: null, current: { id: -1, name: "" } }
if (key === "prev" || key === "current") {
// if key is "prev" or "current", just set its value in the acc. result
acc[catKey][key] = category[key]
return acc
} else {
// key must be related to a nested category, so extract all nested
// categories for the given key and return the new acc. result
return flattenCategory(category[key], acc, key)
}
}, result)
}
// used like
const flatObj = flattenNestedObject(nestedObject)