检索属性“x”属性“y”内的所有对象的带有递归

发布于 2024-12-05 08:25:42 字数 1369 浏览 1 评论 0原文

考虑以下示例:

<script>
var McDuffFamily = {
    name: "Jack McDuff I",
    children: [
        {
            name:"Jack McDuff II",
            children: [
                {
                    name:"Jack McDuff III",
                    children: [
                        {
                            name:"Jack McDuff IV"
                        },
                        {
                            name:"Jonh McDuff I",
                            children: [
                                {
                                    name:"Jonh McDuff I",
                                    children: []
                                }
                            ]
                        }
                    ]
                },
                {
                    name:"Shena McDuff"
                }
            ]
        },
        {
            name:"Poor bastard",
            children: [
                {
                    name:"Citzen I",
                    children: [
                        {
                            name:"Darth Vader"
                        }
                    ]
                },
                {
                    name:"Citzen II",
                    children: []
                }
            ]
        }
    ]
};
</script>

是否有任何轻松的方法来检索所有“Jack McDuff I”后代的姓名?

Consider the following example:

<script>
var McDuffFamily = {
    name: "Jack McDuff I",
    children: [
        {
            name:"Jack McDuff II",
            children: [
                {
                    name:"Jack McDuff III",
                    children: [
                        {
                            name:"Jack McDuff IV"
                        },
                        {
                            name:"Jonh McDuff I",
                            children: [
                                {
                                    name:"Jonh McDuff I",
                                    children: []
                                }
                            ]
                        }
                    ]
                },
                {
                    name:"Shena McDuff"
                }
            ]
        },
        {
            name:"Poor bastard",
            children: [
                {
                    name:"Citzen I",
                    children: [
                        {
                            name:"Darth Vader"
                        }
                    ]
                },
                {
                    name:"Citzen II",
                    children: []
                }
            ]
        }
    ]
};
</script>

Is there any painless way to retrieve the names of all "Jack McDuff I" descendents?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

合约呢 2024-12-12 08:25:42

不使用递归:

var tree =[McDuffFamily];
var kids = [];
for (i=0; i < tree.length; i++) {

   tree[i] && tree.push.apply(tree, tree[i].childrens)
   kids.push(tree[i]);
}
kids; // all children

奇怪部分的分解:

tree[i] && tree.push.apply(tree, tree[i].childrens);

tree[i] &&短路评估 确保我调用时 tree[i] 不为空tree[i].children

tree.push.apply(tree, tree[i].childrens); 使用apply 允许我调用函数,在本例中 Array.push,它在树上接受任意数量的参数。所以该行基本上变成了tree.push(child0, child1, ... childn);。

所以现在tree.length已经增加了当前子节点的子节点数量。

Not using recursion:

var tree =[McDuffFamily];
var kids = [];
for (i=0; i < tree.length; i++) {

   tree[i] && tree.push.apply(tree, tree[i].childrens)
   kids.push(tree[i]);
}
kids; // all children

Breakdown of the weird part:

tree[i] && tree.push.apply(tree, tree[i].childrens);

tree[i] && is used with short-circuit evaluation ensuring that tree[i] is not null when I call tree[i].children

tree.push.apply(tree, tree[i].childrens); using apply which allows me to call a function, in this case Array.push, which takes any number of arguments on tree. So that line basically becomes tree.push(child0, child1, ... childn);.

so now tree.length has been increased by the number of children on the current child.

心如荒岛 2024-12-12 08:25:42

最简单的解决方案是仅使用基本的递归函数:

function traverse(parent, visit) {
    var ii;

    visit(parent.name);

    for (ii = 0; ii < parent.children.length; ii += 1) {
        traverse(parent.children[ii], visit);
    }
}

其中 parent 的初始值为 McDuffFamily ,而 visit 是一个可以执行任何操作的函数。当你访问一个节点时想要做的事情。

The simplest solution is to just use a basic recursive function:

function traverse(parent, visit) {
    var ii;

    visit(parent.name);

    for (ii = 0; ii < parent.children.length; ii += 1) {
        traverse(parent.children[ii], visit);
    }
}

Where the initial value of parent is McDuffFamily and visit is a function that does whatever you want to do when you visit a node.

ぃ双果 2024-12-12 08:25:42

此函数将返回家谱中给定名称的所有后代:

function getDescendants(family, name)
{
     var result = [];

     var iterate = function(node, isDescendant)
     {
         if(isDescendant)
             result.push(node.name);
         else
             isDescendant = (node.name == name);

         for(var i=0; i<node.children.length; i++)
             iterate(node.children[i], isDescendant);
     };

     iterate(family, false);

     return result;
}

它将返回一个包含所有后代名称的数组。

PS:我写了 children 而不是 childrens,因为 children 已经是复数了。

This function will return all the descendants of a given name whitin the family tree:

function getDescendants(family, name)
{
     var result = [];

     var iterate = function(node, isDescendant)
     {
         if(isDescendant)
             result.push(node.name);
         else
             isDescendant = (node.name == name);

         for(var i=0; i<node.children.length; i++)
             iterate(node.children[i], isDescendant);
     };

     iterate(family, false);

     return result;
}

It will return an array that contains the names of all the descendants.

PS: I wrote children instead of childrens, since children is already plural.

绝對不後悔。 2024-12-12 08:25:42
for(var names = [], i = 0, l = McDuffFamily.childrens.length; i < l; i++) {
    names.push(McDuffFamily.childrens[i].name);
}

names; // ['Jack McDuff II', 'Poor bastard']

如果您使用的环境(例如 Node 或使用 MooTools)允许 [].reduce,您也可以这样做:

names = McDuffFamily.childrens.reduce(function(prev, curr) {
    prev.push(curr.name);
}, []);

names; // ['Jack McDuff II', 'Poor bastard']

我认为 [].reduce 看起来更好,但它更费力

for(var names = [], i = 0, l = McDuffFamily.childrens.length; i < l; i++) {
    names.push(McDuffFamily.childrens[i].name);
}

names; // ['Jack McDuff II', 'Poor bastard']

If you are using an environment (like Node or using MooTools) that allows for [].reduce you could also do:

names = McDuffFamily.childrens.reduce(function(prev, curr) {
    prev.push(curr.name);
}, []);

names; // ['Jack McDuff II', 'Poor bastard']

I think [].reduce looks nicer, but it is more taxing

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文