我有一个嵌套子项的JSON对象,我想使用lodash来展平和修改。理想情况下,修订后的JSON将具有嵌套子项所处原始级别的值,并显示其原始路径。
以下是JSON示例:
var data = [
{id: 0, name: 'Australia', children: [
{id: 10, name: 'Melbourne', children: []},
{id: 11, name: 'Sydney', children: [
{id: 100, name: 'Surry Hills', children: []},
{id: 102, name: 'Darlinghurst', children: []}
]},
{id: 13, name: 'Kambalda', children: []}
]},
{id: 1, name: 'Spain', children: [
{id: 20, name: 'Barcelona', children: []},
{id: 21, name: 'Madrid', children: []}
]},
{id: 3, name: 'UK', children: [
{id: 30, name: 'London', children: [
{id: 302, name: 'Knightsbridge', children: []},
{id: 309, name: 'West End', children: []}
]},
{id: 33, name: 'Leeds', children: []},
{id: 35, name: 'Manchester', children: []}
]}
];
我想要生成的转换后的JSON是:
[
{id: 0, name: 'Australia', level: 0, pathname: 'Australia'},
{id: 10, name: 'Melbourne', level: 1, pathname: 'Australia > Melbourne'},
{id: 11, name: 'Sydney', level: 1, pathname: 'Australia > Sydney'},
{id: 100, name: 'Surry Hills', level: 2, pathname: 'Australia > Sydney > Surry Hills'},
{id: 102, name: 'Darlinghurst', level: 2, pathname: 'Australia > Sydney > Darlinghurst'},
{id: 13, name: 'Kambalda', level: 1, pathname: 'Australia > Kambalda'},
{id: 1, name: 'Spain', level: 0, pathname: 'Spain'},
{id: 20, name: 'Barcelona', level: 1, pathname: 'Spain > Barcelona'},
{id: 21, name: 'Madrid', level: 1, pathname: 'Spain > Madrid'},
{id: 3, name: 'UK', level: 0, pathname: 'UK'},
{id: 30, name: 'London', level: 1, pathname: 'UK > London'},
{id: 302, name: 'Knightsbridge', level: 2, pathname: 'UK > London > Knightsbridge'},
{id: 309, name: 'West End', level: 2, pathname: 'UK > London > West End'},
{id: 33, name: 'Leeds', level: 1, pathname: 'UK > Leeds'},
{id: 35, name: 'Manchester', level: 1, pathname: 'UK > Manchester'}
]
我一直在玩_.chain,_.flatten和_.pluck并且无法接近任何东西。
答案 0 :(得分:5)
您可以使用一个简单的递归辅助函数来生成一个数组数组,然后使用_.flattenDeep
来展平它。这样做你想要的:
function flattenMyTree(tree) {
function recurse(nodes, path) {
return _.map(nodes, function(node) {
var newPath = _.union(path, [node.name]);
return [
_.assign({pathname: newPath.join(' > '), level: path.length}, _.omit(node, 'children')),
recurse(node.children, newPath)
];
});
}
return _.flattenDeep(recurse(tree, []));
}
答案 1 :(得分:0)
这个给你预期的答案,但它不是理想的功能风格;
我们的想法是从外面开始展平阵列。在while()
循环的每次迭代中,数组被展平一个级别。该级别的项目将附加到result
,并且这些项目的子项将附加到children
数组。在下一次迭代中,我们将这些孩子压扁。当children
数组中没有其他项目时,表示我们已完成最后一级的处理。最后,我们按pathname
对项目进行排序,有效地将父母及其子女聚集在一起。
var current = data;
var level = 0;
var result = [];
var children = [];
while(current.length > 0) {
result = result.concat(_.map(current, function(item) {
if (!_.isArray(item.path)) {
item.path = [];
}
item.path.push(item.name);
children = children.concat(_.map(item.children, function(child) {
child.path = item.path.slice();
return child;
}));
item.level = level;
item.pathname = item.path.join(" > ");
delete item.path;
delete item.children;
return item;
}));
current = children;
children = [];
level++;
}
result.sort(function(a, b) {
return a.pathname.localeCompare(b.pathname);
});
console.log(result);
答案 2 :(得分:0)
这是基于@mik01aj's answer的,但是在每个步骤中都会变平,并且没有path
参数的默认空数组:
var data = [
{id: 0, name: 'Australia', children: [
{id: 10, name: 'Melbourne', children: []},
{id: 11, name: 'Sydney', children: [
{id: 100, name: 'Surry Hills', children: []},
{id: 102, name: 'Darlinghurst', children: []}
]},
{id: 13, name: 'Kambalda', children: []}
]},
{id: 1, name: 'Spain', children: [
{id: 20, name: 'Barcelona', children: []},
{id: 21, name: 'Madrid', children: []}
]},
{id: 3, name: 'UK', children: [
{id: 30, name: 'London', children: [
{id: 302, name: 'Knightsbridge', children: []},
{id: 309, name: 'West End', children: []}
]},
{id: 33, name: 'Leeds', children: []},
{id: 35, name: 'Manchester', children: []}
]}
];
function flattenMyTree(tree) {
function recurse(nodes, path) {
return _.flatMap(nodes, function(node) {
var newPath = _.union(path, [node.name]);
return _.concat([
_.assign({
pathname: newPath.join(' > '),
level: newPath.length - 1
},
_.omit(node, 'children'))
],
recurse(node.children, newPath)
);
});
}
return recurse(tree);
}
console.log(flattenMyTree(data));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>