我有一个来自JSON的JS数据结构,如下所示:
[
{
"eid": "T1",
"name": "Topic1",
"children": [
{
"eId": "T1.1",
"name": "subtopic1",
"children": []
},
{
"eId": "T1.2",
"name": "subtopic2"
}
]
},
{
"eId": "T2",
"name": "Topic1",
"children": []
}
]
我需要迭代这个并构建另一个看起来像这样的结构:
[
{
"id": "T1",
"text": "Topic1",
"children": [
{
"id": "T1.1",
"text": "subtopic1",
"children": []
},
{
"id": "T1.2",
"text": "subtopic2"
}
]
},
{
"id": "T2",
"text": "Topic1",
"children": []
}
]
我的代码在这里
// topics = the first strucutre
var treeData=[];
for(var i=0,len=topics.length;i<len;++i)
{
var topicElements=topics[i];
var subNodes=[];
var nodes={};
nodes['id']=topicElements.eId;
nodes['text']=topicElements.name;
for (var j =0;j<topicElements.children.length;++j)
{
nodesChildren = topicElements.children;
position = subNodes.length;
subNodes[position] = new Object();
subNodes[position]['id']=nodesChildren[j].eId;
subNodes[position]['text']=nodesChildren[j].name;
}
nodes['children']=subNodes;
treeData.push(nodes);
}
它适用于一个级别,但如果我必须遍历T1.1的子级,那么它将无法工作。你能建议我采用递归方式吗?
答案 0 :(得分:1)
这样的事情可能是:
function redefineData(data) {
var outData = [];
for (var i = 0; i < data.length; i++) {
var obj = { id: data[i].eid, text: data[i].name };
if (data[i].children && data[i].children.length) {
obj.children = redefineData(data[i].children);
}
outData.push(obj);
}
return outData;
}
var treeData = redefineData(topics);
答案 1 :(得分:0)
这是ES6中的通用版本,我认为它更简单:
const renameKey = (oldName, newName) => (xs) =>
xs .map (({[oldName]: old, children, ...rest}) => ({
[newName]: old,
...rest,
...(children ? {children: renameKey (oldName, newName) (children)} : {})
}))
const fixId = renameKey ('eId', 'id')
const data = [{eId: "T1", name: "Topic1", children: [{eId: "T1.1", name: "subtopic1", children: []}, {eId: "T1.2", name: "subtopic2"}]}, {eId: "T2", name: "Topic1", children: []}]
const treeData = fixId (data)
console .log (treeData)
如果您不介意将空children
数组添加到没有数组的数组中,则可以简化一下:
const renameKey = (oldName, newName) => (xs) =>
xs .map (({[oldName]: old, children, ...rest}) => ({
[newName]: old,
...rest,
children: renameKey (oldName, newName) (children || [])
}))
如果样本数据没有错字,并且您实际上需要将eId
和eid
都更改为id
,则可以两次调用它,每次拼写一次。但是,如果您想完全忽略大小写,则需要使用不同的技术(...如果您拥有两个不区分大小写的不同键,也可能会导致问题。)
答案 2 :(得分:-1)
如果真的是“eid”和“eId”的所有实例(请注意,你在这里写了不同的案例!)键应该用“id”替换,所有“name”键都用“text”代替 - 只有这样 - 这个有点hacky方法可能会表现最佳,不经过任何递归循环:
var json = [ "your json code from above" ];
json = JSON.parse(JSON.stringify(json).replace(/"(eId|eid)":/g, '"id":').replace(/"name":/g, '"text":'));
如果差异"eid"
和"eId"
只是一种类型而且总是"eid"
,那么这就足够了:
var json = [ "your json code from above" ];
json = JSON.parse(JSON.stringify(json).replace(/"eid":/g, '"id":').replace(/"name":/g, '"text":'));