[
{
"task": "Project: Shopping",
"duration": 13.25,
"user": "Tommy Maintz",
"iconCls": "task-folder",
"expanded": true,
"children": [
{
"task": "Housewares",
"duration": 1.25,
"user": "Tommy Maintz",
"iconCls": "task-folder",
"children": [
{
"task": "Kitchen supplies",
"duration": 0.25,
"user": "Tommy Maintz",
"leaf": true,
"iconCls": "task"
}, {
"task": "Groceries",
"duration": .4,
"user": "Tommy Maintz",
"leaf": true,
"iconCls": "task",
"done": true
}, {
"task": "Cleaning supplies",
"duration": .4,
"user": "Tommy Maintz",
"leaf": true,
"iconCls": "task"
}, {
"task": "Office supplies",
"duration": .2,
"user": "Tommy Maintz",
"leaf": true,
"iconCls": "task"
}
]
}, {
"task": "Remodeling",
"duration": 12,
"user": "Tommy Maintz",
"iconCls": "task-folder",
"expanded": true,
"children": [
{
"task": "Retile kitchen",
"duration": 6.5,
"user": "Tommy Maintz",
"leaf": true,
"iconCls": "task"
}, {
"task": "Paint bedroom",
"duration": 2.75,
"user": "Tommy Maintz",
"iconCls": "task-folder",
"children": [
{
"task": "Ceiling",
"duration": 1.25,
"user": "Tommy Maintz",
"iconCls": "task",
"leaf": true
}, {
"task": "Walls",
"duration": 1.5,
"user": "Tommy Maintz",
"iconCls": "task",
"leaf": true
}
]
}, {
"task": "Decorate living room",
"duration": 2.75,
"user": "Tommy Maintz",
"leaf": true,
"iconCls": "task",
"done": true
}, {
"task": "Fix lights",
"duration": .75,
"user": "Tommy Maintz",
"leaf": true,
"iconCls": "task",
"done": true
}, {
"task": "Reattach screen door",
"duration": 2,
"user": "Tommy Maintz",
"leaf": true,
"iconCls": "task"
}
]
}
]
}, {
"task": "Project: Testing",
"duration": 2,
"user": "Core Team",
"iconCls": "task-folder",
"children": [
{
"task": "Mac OSX",
"duration": 0.75,
"user": "Tommy Maintz",
"iconCls": "task-folder",
"children": [
{
"task": "FireFox",
"duration": 0.25,
"user": "Tommy Maintz",
"iconCls": "task",
"leaf": true
}, {
"task": "Safari",
"duration": 0.25,
"user": "Tommy Maintz",
"iconCls": "task",
"leaf": true
}, {
"task": "Chrome",
"duration": 0.25,
"user": "Tommy Maintz",
"iconCls": "task",
"leaf": true
}
]
}, {
"task": "Windows",
"duration": 3.75,
"user": "Darrell Meyer",
"iconCls": "task-folder",
"children": [
{
"task": "FireFox",
"duration": 0.25,
"user": "Darrell Meyer",
"iconCls": "task",
"leaf": true
}, {
"task": "Safari",
"duration": 0.25,
"user": "Darrell Meyer",
"iconCls": "task",
"leaf": true
}, {
"task": "Chrome",
"duration": 0.25,
"user": "Darrell Meyer",
"iconCls": "task",
"leaf": true
}, {
"task": "Internet Explorer",
"duration": 3,
"user": "Darrell Meyer",
"iconCls": "task",
"leaf": true
}
]
}, {
"task": "Linux",
"duration": 0.5,
"user": "Aaron Conran",
"iconCls": "task-folder",
"children": [
{
"task": "FireFox",
"duration": 0.25,
"user": "Aaron Conran",
"iconCls": "task",
"leaf": true
}, {
"task": "Chrome",
"duration": 0.25,
"user": "Aaron Conran",
"iconCls": "task",
"leaf": true
}
]
}
]
}
]
[
{
"task": "Project: Shopping",
"duration": 13.25,
"user": "Tommy Maintz",
"iconCls": "task-folder",
"expanded": true,
},
{
"task": "Housewares",
"duration": 1.25,
"user": "Tommy Maintz",
"iconCls": "task-folder",
},
{
"task": "Kitchen supplies",
"duration": 0.25,
"user": "Tommy Maintz",
"leaf": true,
"iconCls": "task"
},
...
]
const getFromTree = (tree, childrenKey, getter = n => n) =>
Array.isArray(tree)
? tree.flatMap(n => [
getter(n),
...getFromTree(n[childrenKey], childrenKey, getter),
])
: [];
// или
function* flatTree(tree, childrenKey) {
if (
tree instanceof Object &&
tree[Symbol.iterator] instanceof Function
) {
for (const n of tree) {
yield n;
yield* getFromTree(n[childrenKey], childrenKey);
}
}
}
const getFromTree = function(tree, childrenKey, getter = n => n) {
const result = [];
for (const stack = this(tree); stack.length;) {
const n = stack.pop();
result.push(getter(n));
stack.push(...this(n[childrenKey]));
}
return result;
}.bind(x => x instanceof Array ? [...x].reverse() : []);
// или
const flatTree = function*(tree, childrenKey) {
const stack = [];
for (let [ i, arr ] = this(tree); ++i < arr.length || stack.length;) {
if (i === arr.length) {
[ i, arr ] = stack.pop();
} else {
yield arr[i];
stack.push([ i, arr ]);
[ i, arr ] = this(arr[i][childrenKey]);
}
}
}.bind(x => [ -1, x?.constructor === Array ? x : [] ]);
// если использовать обычную функцию
const result = getFromTree(tree, 'children', ({ children, ...n }) => n);
// или, генератор
const result = Array.from(flatTree(tree, 'children'), ({ children, ...n }) => n);