使用 Javascript ECMAScript 6 将 table 数据转换为分层树数据的算法
Algorithm to convert a table data to hierarchical tree data using Javascript ECMAScript 6
我有一个 JSON table 数据,想要转换为 JSON 树数据,如下所示。我正在 JavaScript 中使用任何新的 ECMAScript 6 运算符或具有功能方法的语句(不是通过 ES5 的标准递归算法)寻找一种有效的算法?
Table数据:
[
{
"Children":"4th Grand Father"
},
{
"Name":"4th Grand Father",
"Children":"3rd Grand Father"
},
{
"Name":"3rd Grand Father",
"Children":"2nd Grand Father"
},
{
"Name":"2nd Grand Father",
"Children":"Grand Father"
},
{
"Name":"Grand Father",
"Children":"Father"
},
{
"Name":"Grand Father",
"Children":"Uncle"
},
{
"Name":"Uncle",
"Children":"Cousin"
},
{
"Name":"Father",
"Children":"Brother"
},
{
"Name":"Father",
"Children":"Me"
}
]
树数据:
[
{
"Name": "4th Grand Father",
"Children": [
{
"Name": "3rd Grand Father",
"Children": [
{
"Name": "2nd Grand Father",
"Children": [
{
"Name": "Grand Father",
"Children": [
{
"Name": "Father",
"children": [
{
"Name": "Brother"
},
{
"Name": "Me"
}
]
},
{
"Name": "Uncle",
"children": [
{
"Name": "Cousin"
}
]
}
]
}
]
}
]
}
]
}
]
您可以使用这个 ES6 函数,它使用 Map
、箭头函数、解构参数赋值。您甚至可以用扩展语法替换 concat
调用,但我认为这不会带来任何好处:
const makeTree = (data) => {
const hash = data.reduce ( (acc, {Name, Children}) =>
acc.set(Name, (acc.get(Name) || []).concat(Children))
, new Map );
const recurse = (Name) => hash.has(Name)
? { Name, Children: hash.get(Name).map(recurse) }
: { Name };
return recurse(undefined).Children;
}
// Sample data
const data = [
{
"Children":"4th Grand Father"
},
{
"Name":"4th Grand Father",
"Children":"3rd Grand Father"
},
{
"Name":"3rd Grand Father",
"Children":"2nd Grand Father"
},
{
"Name":"2nd Grand Father",
"Children":"Grand Father"
},
{
"Name":"Grand Father",
"Children":"Father"
},
{
"Name":"Grand Father",
"Children":"Uncle"
},
{
"Name":"Uncle",
"Children":"Cousin"
},
{
"Name":"Father",
"Children":"Brother"
},
{
"Name":"Father",
"Children":"Me"
}
];
const result = makeTree(data);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
解释:
hash 变量是从一个空的 Map
构建的,向其中添加由 Name 键入的记录。链接到每个键的值是 children 信息,作为一个数组。当遇到相同的 Name 时(即 acc.get(Name)
returns something),将 child 添加到已经存在的数组中,否则 (|| []
) 创建一个空数组,并向其中添加 child。
一旦 hash 完成,层次结构的顶部由其缺失的 Name (undefined
) 占据,并通过递归 children 在 hash 中查找并添加到最终的 object.
因为结果 object 是一个 object 和一个 Children 数组,而期望的结果实际上就是那个数组,它是返回的 Children 属性。
我有一个 JSON table 数据,想要转换为 JSON 树数据,如下所示。我正在 JavaScript 中使用任何新的 ECMAScript 6 运算符或具有功能方法的语句(不是通过 ES5 的标准递归算法)寻找一种有效的算法?
Table数据:
[
{
"Children":"4th Grand Father"
},
{
"Name":"4th Grand Father",
"Children":"3rd Grand Father"
},
{
"Name":"3rd Grand Father",
"Children":"2nd Grand Father"
},
{
"Name":"2nd Grand Father",
"Children":"Grand Father"
},
{
"Name":"Grand Father",
"Children":"Father"
},
{
"Name":"Grand Father",
"Children":"Uncle"
},
{
"Name":"Uncle",
"Children":"Cousin"
},
{
"Name":"Father",
"Children":"Brother"
},
{
"Name":"Father",
"Children":"Me"
}
]
树数据:
[
{
"Name": "4th Grand Father",
"Children": [
{
"Name": "3rd Grand Father",
"Children": [
{
"Name": "2nd Grand Father",
"Children": [
{
"Name": "Grand Father",
"Children": [
{
"Name": "Father",
"children": [
{
"Name": "Brother"
},
{
"Name": "Me"
}
]
},
{
"Name": "Uncle",
"children": [
{
"Name": "Cousin"
}
]
}
]
}
]
}
]
}
]
}
]
您可以使用这个 ES6 函数,它使用 Map
、箭头函数、解构参数赋值。您甚至可以用扩展语法替换 concat
调用,但我认为这不会带来任何好处:
const makeTree = (data) => {
const hash = data.reduce ( (acc, {Name, Children}) =>
acc.set(Name, (acc.get(Name) || []).concat(Children))
, new Map );
const recurse = (Name) => hash.has(Name)
? { Name, Children: hash.get(Name).map(recurse) }
: { Name };
return recurse(undefined).Children;
}
// Sample data
const data = [
{
"Children":"4th Grand Father"
},
{
"Name":"4th Grand Father",
"Children":"3rd Grand Father"
},
{
"Name":"3rd Grand Father",
"Children":"2nd Grand Father"
},
{
"Name":"2nd Grand Father",
"Children":"Grand Father"
},
{
"Name":"Grand Father",
"Children":"Father"
},
{
"Name":"Grand Father",
"Children":"Uncle"
},
{
"Name":"Uncle",
"Children":"Cousin"
},
{
"Name":"Father",
"Children":"Brother"
},
{
"Name":"Father",
"Children":"Me"
}
];
const result = makeTree(data);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
解释:
hash 变量是从一个空的 Map
构建的,向其中添加由 Name 键入的记录。链接到每个键的值是 children 信息,作为一个数组。当遇到相同的 Name 时(即 acc.get(Name)
returns something),将 child 添加到已经存在的数组中,否则 (|| []
) 创建一个空数组,并向其中添加 child。
一旦 hash 完成,层次结构的顶部由其缺失的 Name (undefined
) 占据,并通过递归 children 在 hash 中查找并添加到最终的 object.
因为结果 object 是一个 object 和一个 Children 数组,而期望的结果实际上就是那个数组,它是返回的 Children 属性。