英文:
how turn an object to an array
问题
我需要从这个对象数组中创建一个具有以下结构的数组数组:
array = [[A, A1, A1a],
[A1b],
[A1c],
[A2, A2a],
[A2b],
[A3, A3a],
[A3b],
[A3c],
[A3d],
[A4, A4a],
[A4b],
[A4c],
[B, B1, B1a]
以此类推]
目的是为Google电子表格中的每个数组写一行。
我在使用forEach
方法时感到困惑,因为在每个对象中,child
键包含其他对象数组,而这些对象数组本身也具有child
,我不知道如何在这种层次结构中进行迭代。
英文:
I have an array of object:
arrayOfObjects = [
{
"name": "A",
"child": [
{
"name": "A1",
"child": [
{
"name": "A1a"
},
{
"name": "A1b"
},
{
"name": "A1c"
}
]
},
{
"name": "A2",
"child": [
{
"name": "A2a"
},
{
"name": "A2b"
}
]
},
{
"name": "A3",
"child": [
{
"name": "A3a"
},
{
"name": "A3b"
},
{
"name": "A3c"
},
{
"name": "A3d"
}
]
},
{
"name": "A4",
"child": [
{
"name": "A4a"
},
{
"name": "A4b"
},
{
"name": "A4c"
}
]
}
]
},
{
"name": "B",
"child": [
{
"name": "B1",
"child": [
{
"name": "B1a"
},
{
"name": "B1b"
}
]
},
{
"name": "B2",
"child": [
{
"name": "B2a"
},
{
"name": "B2b"
}
]
},
{
"name": "B3",
"child": [
{
"name": "B3A"
},
{
"name": "B3b"
},
{
"name": "B3c"
},
{
"name": "B3d"
},
{
"name": "B3e"
}
]
}
]
},
{others objects with same structure}
]
I need to create an array of arrays from this array of object with this structure :
array = [[A,A1,A1a],
[A1b],
[A1c],
[A2,A2a],
[A2b],
[A3,A3a],
[A3b],
[A3c],
[A3d],
[A4,A4a],
[A4b],
[A4c],
[B,B1,B1a]
and so on]
The purpose is to writ a line for each array in a Google spreadsheet.
I'm getting lost with the forEach method, in each object, the child key contains other arrays of object having child themselves, I don't know how to iterate in this hierarchy
答案1
得分: -1
你可以使用自包含的递归(不依赖全局累加器或传递的上下文)通过在递归调用的最深层结果在返回时分布到每个层级上来实现这一点。在这里,使用了一个嵌套的 for...of
循环处理递归调用的结果。
const arrayOfObjects = [
{ name: 'A', child: [
{ name: 'A1', child: [
{ name: 'A1a' },
{ name: 'A1b' },
{ name: 'A1c' },
] },
{ name: 'A2', child: [
{ name: 'A2a' },
{ name: 'A2b' }
] },
// 其他省略...
] },
{ name: 'B', child: [
{ name: 'B1', child: [
{ name: 'B1a' },
{ name: 'B1b' }
] },
{ name: 'B2', child: [
{ name: 'B2a' },
{ name: 'B2b' }
] },
// 其他省略...
] },
];
const condenseArray = (arr) => {
const res = [];
let lvl = [];
for (const { name, child } of arr) {
lvl.push(name);
if (child?.length) {
for (const n of condenseArray(child)) {
lvl.push(...n);
res.push(lvl);
lvl = [];
}
} else {
res.push(lvl);
lvl = [];
}
}
return res;
};
const result = condenseArray(arrayOfObjects);
for (const arr of result) {
console.log(`[ ${arr.map((n) => '${n}').join(', ')} ]`.padStart(20, ' '));
}
输出结果:
[
['A', 'A1', 'A1a'],
['A1b'],
['A1c'],
['A2', 'A2a'],
['A2b'],
// 其他省略...
['B', 'B1', 'B1a'],
['B1b'],
['B2', 'B2a'],
// 其他省略...
]
但在逻辑和输出上,更清晰的做法是为每个子元素创建完整的行。
const arrayOfObjects = [
// 与上文相同...
];
const condenseArray = (arr) => {
const res = [];
for (const { name, child } of arr) {
let lvl = [name];
if (child?.length) {
for (const n of condenseArray(child)) {
res.push([...lvl, ...n]);
}
} else {
res.push(lvl);
}
}
return res;
};
const result = condenseArray(arrayOfObjects);
for (const arr of result) {
console.log(`[ ${arr.map((n) => '${n}').join(', ')} ]`.padStart(20, ' '));
}
输出结果:
[
['A', 'A1', 'A1a'],
['A', 'A1', 'A1b'],
['A', 'A1', 'A1c'],
['A', 'A2', 'A2a'],
['A', 'A2', 'A2b'],
// 其他省略...
]
英文:
You can achieve this using self-contained recursion (not relying on a global accumulator or passed context) by distributing the results of the deepest recursive calls across each level on the way back up. Here using a nested for...of
loop on the results of the recursive call.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const arrayOfObjects = [{ name: 'A', child: [{ name: 'A1', child: [{ name: 'A1a' }, { name: 'A1b' }, { name: 'A1c' }], }, { name: 'A2', child: [{ name: 'A2a' }, { name: 'A2b' }] }, { name: 'A3', child: [{ name: 'A3a' }, { name: 'A3b' }, { name: 'A3c' }, { name: 'A3d' },], }, { name: 'A4', child: [{ name: 'A4a' }, { name: 'A4b' }, { name: 'A4c' }], },], }, { name: 'B', child: [{ name: 'B1', child: [{ name: 'B1a' }, { name: 'B1b' }] }, { name: 'B2', child: [{ name: 'B2a' }, { name: 'B2b' }] }, { name: 'B3', child: [{ name: 'B3A' }, { name: 'B3b' }, { name: 'B3c' }, { name: 'B3d' }, { name: 'B3e' },], },], },];
const condenseArray = (arr) => {
const res = [];
let lvl = [];
for (const { name, child } of arr) {
lvl.push(name);
if (child?.length) {
for (const n of condenseArray(child)) {
lvl.push(...n);
res.push(lvl);
lvl = [];
}
} else {
res.push(lvl);
lvl = [];
}
}
return res;
};
const result = condenseArray(arrayOfObjects);
for (const arr of result) {
console.log(`[ ${arr.map((n) => `'${n}'`).join(', ')} ]`.padStart(20, ' '));
}
/* Output
[
['A', 'A1', 'A1a'],
['A1b'],
['A1c'],
['A2', 'A2a'],
['A2b'],
...
['B', 'B1', 'B1a'],
['B1b'],
['B2', 'B2a'],
...
]
*/
<!-- language: lang-css -->
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}
<!-- end snippet -->
But it is clearer both in logic and output to simply create complete rows for each child.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const arrayOfObjects = [{ name: 'A', child: [{ name: 'A1', child: [{ name: 'A1a' }, { name: 'A1b' }, { name: 'A1c' }], }, { name: 'A2', child: [{ name: 'A2a' }, { name: 'A2b' }] }, { name: 'A3', child: [{ name: 'A3a' }, { name: 'A3b' }, { name: 'A3c' }, { name: 'A3d' },], }, { name: 'A4', child: [{ name: 'A4a' }, { name: 'A4b' }, { name: 'A4c' }], },], }, { name: 'B', child: [{ name: 'B1', child: [{ name: 'B1a' }, { name: 'B1b' }] }, { name: 'B2', child: [{ name: 'B2a' }, { name: 'B2b' }] }, { name: 'B3', child: [{ name: 'B3A' }, { name: 'B3b' }, { name: 'B3c' }, { name: 'B3d' }, { name: 'B3e' },], },], },];
const condenseArray = (arr) => {
const res = [];
for (const { name, child } of arr) {
let lvl = [name];
if (child?.length) {
for (const n of condenseArray(child)) {
res.push([...lvl, ...n]);
}
} else {
res.push(lvl);
}
}
return res;
};
const result = condenseArray(arrayOfObjects);
for (const arr of result) {
console.log(`[ ${arr.map((n) => `'${n}'`).join(', ')} ]`.padStart(20, ' '));
}
/* Output
[
['A', 'A1', 'A1a'],
['A', 'A1', 'A1b'],
['A', 'A1', 'A1c'],
['A', 'A2', 'A2a'],
['A', 'A2', 'A2b'],
...
]
*/
<!-- language: lang-css -->
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}
<!-- end snippet -->
答案2
得分: -2
[ [ 'A', 'A1', 'A1a' ],
[ 'A1b' ],
[ 'A1c' ],
[ 'A2', 'A2a' ],
[ 'A2b' ],
[ 'A3', 'A3a' ],
[ 'A3b' ],
[ 'A3c' ],
[ 'A3d' ],
[ 'A4', 'A4a' ],
[ 'A4b' ],
[ 'A4c' ],
[ 'B', 'B1', 'B1a' ],
[ 'B1b' ],
[ 'B2', 'B2a' ],
[ 'B2b' ],
[ 'B3', 'B3A' ],
[ 'B3b' ],
[ 'B3c' ],
[ 'B3d' ],
[ 'B3e' ] ]
英文:
I've done that...
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const arrayOfObjects =
[ { name: 'A', child:
[ { name: 'A1', child:
[ { name: 'A1a' }, { name: 'A1b' }, { name: 'A1c' }
] }
, { name: 'A2', child:
[ { name: 'A2a' }, { name: 'A2b' }
] }
, { name: 'A3', child:
[ { name: 'A3a' }, { name: 'A3b' }, { name: 'A3c' }, { name: 'A3d' }
] }
, { name: 'A4', child:
[ { name: 'A4a' }, { name: 'A4b' }, { name: 'A4c' }
] } ] }
, { name: 'B', child:
[ { name: 'B1', child:
[ { name: 'B1a' }, { name: 'B1b' }
] }
, { name: 'B2', child:
[ { name: 'B2a' }, { name: 'B2b' }
] }
, { name: 'B3', child:
[ { name: 'B3A' }, { name: 'B3b' }, { name: 'B3c' }, { name: 'B3d' }, { name: 'B3e' }
] } ] } ];
const res = [], elm = [];
const AddElm = arr =>
{
arr.forEach(({name,child}) =>
{
elm.push(name)
if (!!child)
AddElm(child);
else
{
res.push([...elm]);
elm.length = 0;
}
});
}
AddElm(arrayOfObjects);
console.log( res );
<!-- language: lang-css -->
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}
<!-- end snippet -->
synthetic result
[ [ 'A', 'A1', 'A1a' ]
, [ 'A1b' ]
, [ 'A1c' ]
, [ 'A2', 'A2a' ]
, [ 'A2b' ]
, [ 'A3', 'A3a' ]
, [ 'A3b' ]
, [ 'A3c' ]
, [ 'A3d' ]
, [ 'A4', 'A4a' ]
, [ 'A4b' ]
, [ 'A4c' ]
, [ 'B', 'B1', 'B1a' ]
, [ 'B1b' ]
, [ 'B2', 'B2a' ]
, [ 'B2b' ]
, [ 'B3', 'B3A' ]
, [ 'B3b' ]
, [ 'B3c' ]
, [ 'B3d' ]
, [ 'B3e' ]
]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论