【问题标题】:How can I make this recursive?我怎样才能使这个递归?
【发布时间】:2014-01-05 13:03:46
【问题描述】:

包括二维数组的声明,我怎样才能使下面的递归?我希望它迭代直到没有“children()”。

    self.buildRelationships = function () {
        relationships = [];
        relationships[0] = [];
        relationships[1] = [];
        relationships[2] = [];
        relationships[3] = [];
        relationships[0][0] = self.name();
        $.each(self.children(), function(i, child) {
            relationships[1][i] = child.name();
            $.each(child.children(), function (j, grandchild) {
                relationships[2][j] = grandchild.name();
                $.each(grandchild.children(), function (k, greatgrandchild) {
                    relationships[3][k] = greatgrandchild.name();
                })
            })
        })
    }

目标的可视化

鉴于此数据:

  • 我!
    • 鲍勃
      • 詹姆斯
        • 戴尔
      • 史蒂夫
    • 比尔
      • 弗雷德
        • 欧文
        • 帕特里克

.children() 仅返回直接子代:

Bob.children() 将返回“James”和“Steve”。

Me!.children() 将返回“Bob”和“Bill”。

接受的答案将创建如下所示的数据:

relationships[0] = "Me!" //this will always have a length of only 1
relationships[1] = "Bob", "Bill"
relationships[2] = "James", "Steve", "Fred"
relationships[3] = "Dale", "Owen", "Patrick"

【问题讨论】:

  • 您使用 $.each 有什么特别的原因吗?这似乎是无缘无故的很多开销。
  • @VoronoiPotato: $.each 是一种遍历数组和对象的通用方法。甚至$(...).each 也不会很昂贵,因为它只是迭代已经选择的元素。此时没有发生 DOM 交互。
  • @VoronoiPotato:嗯?我只是.forEach 是本机方法。 .map.forEach 是不同的。总之,不是讨论这个的合适地方。我尊重您的意见(使用更快的方式),但不要做出虚假陈述($.each 旨在迭代 DOM 元素)。
  • @VoronoiPotato:上次:你说的是$(...).each,我说的是$.each,这就是OP使用的。你注意到 URL 的不同了吗?你:api.jquery.com/each,我:api.jquery.com/jQuery.each。我也可以为您引用:“$.each() 函数与 $(selector).each() 不同,后者用于专门迭代 jQuery 对象。$.each( ) 函数可用于迭代任何集合,无论是对象还是数组。” 我希望现在已经解决了。
  • 为什么人们不使用 VanillaJS 是个谜

标签: javascript jquery recursion multidimensional-array


【解决方案1】:
self.buildRelationships = function () {
        relationships = [];
        relationships[0] = [];
        relationships[1] = [];
        relationships[2] = [];
        relationships[3] = [];
        relationships[0][0] = self.name();

        var recursive = function(level) {

            return function(i, child) {
               relationships[level] = relationships[level] || [];

               relationships[level].push(child.name());
               $.each(child.children(), recursive(level + 1));
            }
        }

        $.each(self.children(), recursive(1));
    }

【讨论】:

  • 很多?我们在这里讨论的是每层的字节数。从外观上看,他预计有 4 个级别。在这种情况下,我不会担心。显然,如果我们要进入数千个级别,递归解决方案将不是可行的方法,但 OP 要求递归,所以我给出递归。
  • 我假设我可以在递归函数中添加“relationships[i] = []”?
  • 我认为你更愿意做关系[level] = []。已编辑。
  • 当然,我就是这个意思。谢谢。
  • 这很好用,但最后会增加一个空代。不过很容易修复。谢谢。
【解决方案2】:

以下是我的处理方式:

self.buildRelationships = function () {
    var relationships = [];
    addToLevel(self, 0);
    return relationships;

    function addToLevel(node, levelIndex) {
        $.each(node.children(), function (i, child) {
            if (relationships.length <= levelIndex) { relationships.push([]) }
            relationships[levelIndex].push(child.name()); 
            addToLevel(child, levelIndex + 1);
        });
    }
}

(我更喜欢使用 Underscore/Lodash 进行数据处理,并为 DOM 内容保留 jQuery。但假设只使用 jQuery。)

【讨论】:

  • "无法调用未定义的方法'push'"
  • 我编码了这个盲注。如果您可以制作一个我可以测试的 Jsfiddle,我很乐意调试。有些东西可能没有初始化,但我没有时间建立一个测试台来解决这个问题。如果您想使用这种方法,请在找到时随时添加更正。
  • @ScottBeeson 对于它的价值,这是一个栅栏错误。现已修复。
【解决方案3】:

&为了好玩,这里有一个递归 jQuery 插件,可以在容器上调用,该容器可能是也可能不是单例“eve”生物(取决于容器元素是否定义了 name 属性):

jsfiddle

$.fn.getImps=function(imps, i)
{
    if (!$.isArray(imps)) 
        throw new Error("oook: getImps requires an empty array!");
    i=(typeof i !== "undefined" ? i : 0);

    if (this.is("[name]"))
        (imps[i] || (imps[i]=[])).push(this.attr("name")) && i++;
    this.children().each(function(){ $(this).getImps(imps,i) });
} 


顺便说一句:因为这是一个breadth-first traversal,并且通常使用基于非递归队列的算法来实现......:

jsfiddle

//expects a singleton container id 
var getImps=function(id)
{      
    var imps=[];     
    for(var o=$(id), a; (o=o.children("[name]")).length && imps.push(a=[]);)
        o.each(function() { a.push($(this).attr("name")) });
    return imps;
}

(= 但只是说.. =)


Oook:嗯,你的生物似乎正在经历某种无性繁殖~它们可能是……蚜虫吗?

【讨论】:

    猜你喜欢
    • 2014-01-07
    • 1970-01-01
    • 1970-01-01
    • 2016-03-07
    • 2021-10-06
    • 2010-10-16
    • 2017-03-23
    • 2019-01-01
    • 1970-01-01
    相关资源
    最近更新 更多