javascript - Flatten an array of unknown deep objects, with named properties, in Async/Await JavaScript (or better TypeScript)
问题描述
I've already seen that such questions have been answered 1000 times, but I can't get it.
I have an array with various unknown depth objects, only in the property children
are/might be more objects of the same schema as the parent object.
I need all objects regardless of their dependency in a list.
Here is an example of the raw data:
[
{
"id": "root________",
"title": "",
"index": 0,
"dateAdded": 1607859798059,
"type": "folder",
"dateGroupModified": 1607859798494,
"children": [
{
"id": "menu________",
"title": "Lesezeichen-Menü",
"index": 0,
"dateAdded": 1607859798059,
"type": "folder",
"parentId": "root________",
"dateGroupModified": 1607859798427,
"children": [
{
"id": "vzj790Oc5ncn",
"title": "Mozilla Firefox",
"index": 0,
"dateAdded": 1607859798427,
"type": "folder",
"parentId": "menu________",
"dateGroupModified": 1607859798427,
"children": [
{
"id": "YIjZdOQ4I3nz",
"title": "Hilfe und Anleitungen",
"index": 0,
"dateAdded": 1607859798427,
"type": "bookmark",
"url": "https://support.mozilla.org/de/products/firefox",
"parentId": "vzj790Oc5ncn"
},
{
"id": "cHfBIRuk3-d0",
"title": "Firefox anpassen",
"index": 1,
"dateAdded": 1607859798427,
"type": "bookmark",
"url": "https://support.mozilla.org/de/kb/customize-firefox-controls-buttons-and-toolbars?utm_source=firefox-browser&utm_medium=default-bookmarks&utm_campaign=customize",
"parentId": "vzj790Oc5ncn"
},
{
"id": "wBPLt_b_UKWN",
"title": "Machen Sie mit",
"index": 2,
"dateAdded": 1607859798427,
"type": "bookmark",
"url": "https://www.mozilla.org/de/contribute/",
"parentId": "vzj790Oc5ncn"
},
{
"id": "LngszJqD2COI",
"title": "Über uns",
"index": 3,
"dateAdded": 1607859798427,
"type": "bookmark",
"url": "https://www.mozilla.org/de/about/",
"parentId": "vzj790Oc5ncn"
}
]
}
]
},
{
"id": "toolbar_____",
"title": "Lesezeichen-Symbolleiste",
"index": 1,
"dateAdded": 1607859798059,
"type": "folder",
"parentId": "root________",
"dateGroupModified": 1607859798494,
"children": [
{
"id": "DnLPkDUWf4k7",
"title": "Erste Schritte",
"index": 0,
"dateAdded": 1607859798494,
"type": "bookmark",
"url": "https://www.mozilla.org/de/firefox/central/",
"parentId": "toolbar_____"
}
]
},
{
"id": "unfiled_____",
"title": "Weitere Lesezeichen",
"index": 3,
"dateAdded": 1607859798059,
"type": "folder",
"parentId": "root________",
"dateGroupModified": 1607859798407,
"children": []
},
{
"id": "mobile______",
"title": "Mobile Lesezeichen",
"index": 4,
"dateAdded": 1607859798081,
"type": "folder",
"parentId": "root________",
"dateGroupModified": 1607859798407,
"children": []
}
]
}
]
I have written a repeating function that goes through the nested elements recursively, however within the repeater function it is not being called again despite the repeat call.
How do I call the custom async function again in TypeScript? recursively
repeater = async (node: any): Promise<any> => {
const summeryRepeater : any[] = [];
const children = await this.getChildren(node.id);
if (children.length >= 1) {
for (const node of children) {
summeryRepeater.push(node)
await this.repeater(node)
}
}
return summeryRepeater
}
// TODO
// eslint-disable-next-line @typescript-eslint/no-explicit-any
getTreeList = async (): Promise<any> => {
const summery : any[] = [];
const node = await browser.bookmarks.get("root________"); // return non children
summery.push(node[0])
const children = await this.getChildren(node[0].id); // return non children
if (children.length >= 1) {
for (const node of children) {
summery.push(node)
// // Repeat start
const repeater = await this.repeater(node)
for (const nodeR of repeater) {
summery.push(nodeR)
}
// // Repeat end
}
}
return summery
}
I have been stuck here for days and really need your help. Can anyone give me a hint?
THX, John
解决方案
首先,像这样的任务实际上并不需要 async/await 或 Promise - 扁平化嵌套数据结构没有什么异步的。
由于您发布的代码不完整,因此很难使用它,因此我只是从头开始制作了一个代码示例,它将采用您的嵌套结构并返回一个扁平版本。
const flattenStructure = entries => (
entries
.flatMap(entry => [entry, ...flattenStructure(entry.children || [])])
.flat()
)
如果您对上面的示例数据调用 flattenStructure(),您会看到它会生成包含在您的结构中的所有对象的列表。它不会修改对象,因此某些对象仍然具有 arrayOfObjects 属性,列出了它们的后代是什么。
该代码片段中使用的函数/概念的引用:
- array.flatMap()与array.map()后跟array.flat()相同。
- 传播语法(这个东西:“...”)
推荐阅读
- python - 如何使字典中的每个“用户”成为键以及它们所属的所有“组”的值?
- ssl - 通过 nginx 连接以保护 websocket
- powershell - 如何使用 Invoke-Command 作为域管理员在远程服务器上执行命令?
- python - Matplotlib - 在股票图的高点和低点之间画一条直线的最佳方法是什么?
- mysql - MySQL,将一组记录与另一组记录进行比较
- twilio - Twilio 队列连接到错误的呼叫
- vue.js - vue v-for:在 vue i18n 中使用 switch 进行翻译
- c++ - 运行时链接器问题:“加载共享库时出错”
- c++ - 如何编写多线程 lua 脚本或让多个脚本在 C++ 程序中一起运行
- sql - 试图返回表 A 中不存在于表 B 中的值