【问题标题】:Edit property names recursively递归编辑属性名称
【发布时间】:2015-04-23 15:21:07
【问题描述】:

我有一个来自 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 的子级,那么它将不起作用。你能建议我一种递归的方式吗?

【问题讨论】:

    标签: javascript recursion


    【解决方案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);
    

    【讨论】:

      【解决方案2】:

      这是 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 || [])
        }))
      

      如果示例数据没有拼写错误,并且您实际上需要将eIdeid 都更改为id,则可以调用两次,每次拼写一次。但是如果你想完全忽略大小写,那么这将需要一种不同的技术(......如果你有两个不区分大小写相同的不同键,也可能会导致问题。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-11
        • 2021-11-30
        • 2017-02-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-08
        相关资源
        最近更新 更多