用于查找所有子组的递归函数

时间:2015-06-23 01:01:58

标签: javascript recursion tree

我在JavaScript中创建递归函数时遇到了麻烦。 我有一个包含组的数组,其中每个组都有一个唯一的ID,一个名称和一个父母" (引用组的ID)。

我的递归函数的要点是列出从一个点开始的所有子组。它就像一张组织结构图,从顶部开始,将每个子组列为子女。

数组 groups 包含以下数据:

var groups = [{ id: 1, naam: "Directie", parent: 1 },
              { id: 2, naam: "Marketing", parent: 1 },
              { id: 3, naam: "Human Resources", parent: 1 },
              { id: 4, naam: "Financieel", parent: 2 },
              { id: 5, naam: "Verkoop", parent: 3 }];

以下代码仅可用于查找直接子项,但不会深入搜索下一级别。

var group = $("#groepen :selected").val();

var output = "";
var hasChildren = false;
var children = 0;

for(var i = 0; i < groups.length; i++)
{
    if(groups[i].parent === parseInt(group))
    {
        children++;
        output += "Group ID: " + groups[i].id + "\nGroup name: " + groups[i].naam + 
             "\nGroup parent: " + groups[i].parent + 
             "\n---------------------------------------------\n";
        hasChildren = true;
    }
}

output = "Children: " + children + 
   "\n---------------------------------------------\n" + output;

if(!hasChildren)
{
    output = "No data found";   
}

$("#groups").html(output);

因此,在以下情况下,变量 group 将是&#34; Directie&#34;,我会得到以下结果: - Directie(root) - 营销 - 人力资源

但它没有深入到下一个级别。 我想要的结果是: - Directie(root) - 营销 - Financieel - 人力资源 - Verkoop

订单本身并不重要,我只想列出作为&#34; Directie&#34;的子组的所有组。

注意:我还使用当前代码制作了fiddle。要测试一下,只需点击&#34;搜索&#34;按钮并选择&#34; root&#34;来自下拉列表的小组。

2 个答案:

答案 0 :(得分:1)

为了让你的函数递归,它需要自己调用。由于您正在寻找父子关系,因此您必须从父母开始,然后使用函数来查找每个孩子。在循环内部再次调用您的函数,但将当前子项传递给函数以查找该项目的子项。我不确定您希望如何输出数据,但此功能会获得您在问题中描述的顺序。

var groups = [{
    id: 1,
    naam: "Directie",
    parent: 0
}, {
    id: 2,
    naam: "Marketing",
    parent: 1
}, {
    id: 3,
    naam: "Human Resources",
    parent: 1
}, {
    id: 4,
    naam: "Financieel",
    parent: 2
}, {
    id: 5,
    naam: "Verkoop",
    parent: 3
}];

function getChildren( parent ) {

    for(var i = 0; i < groups.length; i++) {

        if (groups[i].parent === parent.id ) {
            var output = "Group ID: " + groups[i].id + "\nGroup name: " + groups[i].naam + "\nGroup parent: " + groups[i].parent + "\n---------------------------------------------\n";

            $('textarea').append( output );
            getChildren( groups[i] );
        }
    }
}

getChildren( groups[0] )

JSFiddle

答案 1 :(得分:0)

您不需要递归函数来提取最深节点和叶子中的所有子节点。这个功能可以做你想要的:

function getSubTree(tree, root) {
    var i, j, nextNodes, subtree = [], currentNodes = [root];
    while (currentNodes.length > 0) {
        subtree = subtree.concat(currentNodes);
        nextNodes = [];
        for (i=0; i < currentNodes.length; i++) {
            for (j=0; j < tree.length; j++) {
                if (tree[j].parent == currentNodes[i].id) {
                    if (currentNodes[i].id == tree[j].id) {
                        continue;
                    }
                    nextNodes.push(tree[j]);
                }
            }
        }
        currentNodes = nextNodes;
    }
    return subtree;
}

在您的情况下,您可以像这样运行它:

var subTree = getSubTree(groups, {
    id: 1,
    naam: "Directie",
    parent: 1
});

tree或您在group中调用的对象必须是idparent的对象数组(与此处的数据结构相同)。

一句话中的算法:尝试将tree中的节点添加到subtree,直到找不到与子树相关的任何节点为止。