【问题标题】:Recursive iteration over dynamically nested object array动态嵌套对象数组的递归迭代
【发布时间】:2013-04-17 13:43:15
【问题描述】:

我正在使用 Angular JS 及其示例之一:http://jsfiddle.net/furf/EJGHX/

我需要在更新功能发生时获取数据,并在发送到服务器之前为其添加一些值。 (如果用 Angular 而不是 js 做这个会更好让我知道)

我正在尝试获取“parentid”和“index”并更新子项。

这是我循环的数据

{
    "children": [{
        "id": "5",
        "parentid": "0",
        "text": "Device Guides",
        "index": "1",
        "children": [{
            "id": "10",
            "index": "0",
            "text": "Grandstream GXP-21XX"
        }, {
            "id": "11",
            "index": "1",
            "text": "Polycom Soundstation/Soundpoint"
        }, {
            "id": "23",
            "index": "2",
            "text": "New Polycom"
        }]
    }, {
        "id": "6",
        "parentid": "0",
        "text": "Pre-Sales Evaluation",
        "index": "0",
        "children": []
    }, {
        "id": "7",
        "parentid": "0",
        "text": "Router Setup Guides",
        "index": "2",
        "children": [{
            "id": "9",
            "index": "0",
            "text": "Sonicwall"
        }, {
            "id": "12",
            "index": "1",
            "text": "Cisco"
        }]
    }, {
        "id": "9",
        "parentid": "7",
        "text": "Sonicwall",
        "index": "0",
        "children": []
    }, {
        "id": "10",
        "parentid": "5",
        "text": "Grandstream GXP-21XX",
        "index": "0",
        "children": []
    }, {
        "id": "11",
        "parentid": "5",
        "text": "Polycom Soundstation/Soundpoint",
        "index": "1",
        "children": []
    }, {
        "id": "12",
        "parentid": "7",
        "text": "Cisco",
        "index": "1",
        "children": []
    }, {
        "id": "15",
        "parentid": "0",
        "text": "Post-Sales Implementation Check List",
        "index": "7",
        "children": [{
            "id": "16",
            "index": "0",
            "text": "Porting and New Number Details"
        }, {
            "id": "18",
            "index": "1",
            "text": "Partner Setup"
        }, {
            "id": "19",
            "index": "2",
            "text": "test"
        }, {
            "id": "21",
            "index": "3",
            "text": "test"
        }]
    }, {
        "id": "16",
        "parentid": "15",
        "text": "Porting and New Number Details",
        "index": "0",
        "children": []
    }, {
        "id": "18",
        "parentid": "15",
        "text": "Partner Setup",
        "index": "1",
        "children": []
    }, {
        "id": "19",
        "parentid": "15",
        "text": "test",
        "index": "2",
        "children": []
    }, {
        "id": "20",
        "parentid": "0",
        "text": "test",
        "index": "11",
        "children": []
    }, {
        "id": "21",
        "parentid": "15",
        "text": "test",
        "index": "3",
        "children": []
    }, {
        "id": "23",
        "parentid": "5",
        "text": "New Polycom",
        "index": "2",
        "children": []
    }, {
        "id": "24",
        "parentid": "0",
        "text": "Test Markup",
        "index": "14",
        "children": []
    }, {
        "id": "25",
        "parentid": "0",
        "text": "test",
        "index": "15",
        "children": []
    }]
}

这就是我目前循环的方式,但它只获得第一个维度

for (i = 0, l = data.length; i < l; i++) {
    parentid = data[i].id == null ? '0' : data[i].id;
    data[i].index = i;
    if (data[i].children) {
        if (data[i].children.length > 0) {
            for (q = 0, r = data[i].children.length; q < r; q++) {
                data[i].children[q].parentid = parentid;
                data[i].children[q].index = q;
            }
        }
    }
}

我在另一个小提琴上找到了这个,但我不知道如何获取 parentid 或索引

$.each(target.children, function(key, val) { recursiveFunction(key, val) });

    function recursiveFunction(key, val) {
        actualFunction(key, val);
        var value = val['children'];
        if (value instanceof Object) {
            $.each(value, function(key, val) {
                recursiveFunction(key, val)
            });
        }

    }


function actualFunction(key, val) {}

【问题讨论】:

    标签: javascript jquery angularjs


    【解决方案1】:

    如果我对您的理解正确,您希望每个“孩子”都有一个 parentID(由其父级定义;否则为 0)和一个 index(基于其在同级集中的位置)。

    function normalize(parent) {
        if (parent && parent.children) {
            for (var i = 0, l = parent.children.length; i < l; ++i) {
                var child = parent.children[i];
                child.index = i;
                if (!child.parentId) child.parentId = parent.id || '0';
                normalize(child);
            }
        }
    }
    
    normalize(data);
    

    【讨论】:

    • 看起来应该可以了。我对其进行了测试,但似乎无法设置父 ID。以下是它的集成方式:jsfiddle.net/EJGHX/38 第 213 行,如果您添加新的子项并移动它,您将在控制台中看到结果。
    • @Stephen - 我快速查看了您提供的示例中的代码,似乎没有任何节点具有与之关联的 ID。您希望在哪里设置此信息?目前,每个child.parentId 都被设置为'0',因为parent.id 不存在。
    【解决方案2】:

    递归是在同一个函数中调用函数。您的示例根本不是递归;

    function runRecursive(input) {
        for (var i = 0, l = input.length; i < l; i++) {
            var current = input[i];
    
            parentid = current.id == null ? '0' : current.id;
            current.index = i;
            if (current.children && current.children.length > 0) {
                runRecursive(current.children);
            };
        };
    };
    
    runRecursive(data.children);
    

    你也应该用var关键字定义i和l,否则它将位于窗口上下文中并且递归逻辑将被破坏。 虽然我不明白 parentid 变量的用途以及为什么它在可见代码之外定义。

    【讨论】:

    • Tommi,感谢您的回复。如果您查看 Andrews 的答案,他的答案更接近我正在寻找的内容,我正在从父对象的 id 定义父 id。
    • 确实如此。不要忘记为未来的用户标记安德鲁的答案。
    猜你喜欢
    • 2017-02-02
    • 1970-01-01
    • 1970-01-01
    • 2020-04-24
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    相关资源
    最近更新 更多