重构工作递归代码 (hasFiveDIVs) 以遍历 DOM [英] refactoring working recursion code (hasFiveDIVs) for traversing the DOM

查看:51
本文介绍了重构工作递归代码 (hasFiveDIVs) 以遍历 DOM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

@oriol 为我今天处理的一个问题提供了一个惊人的两行递归解决方案.

@oriol provided an amazing two line recursive solution for a problem I was working on today.

function numOccurencesRecursive(arr, val) {
  if (!arr.length) return 0;
  return (arr[0] === val ? 1 : 0) + numOccurencesRecursive(arr.slice(1), val);
}

我受到启发,重构了我昨天编写的一些意大利面条式代码:

I was inspired to refactor some spagetti-ish code that I wrote yesterday:

//returns a boolean
    function containsFiveOrMoreDivs(domElement) {
      var count = 0;

  function doCount(domElement) {
    if (domElement && domElement.tagName === "DIV") {
      count++;
    }

    if (count >= 5) {
      return true;
    }

    if (domElement.hasChildNodes()) {
      var children = domElement.childNodes;
      for (var i = 0; i < children.length; i++) {
        if (doCount(children[i])) {
          return true
        }
      };
    };

    return false;
  }

  return doCount(domElement)
}
containsFiveOrMoreDivs(document);

这是尝试:

function containsFiveOrMoreDivsPureRecursion(domElement) {
  if (!domElement && domElement.tagName !== "DIV") {
    return 0;
  }
  return (domElement.tagName === "DIV" ? 1 : 0) + containsFiveOrMoreDivsPureRecursion(domElement.childNodes()); //?
}

在这个版本中我将如何递归遍历所有子节点?我在做什么可能吗?

how would I loop through all the child nodes recursively in this version? Is what I'm doing possible?

推荐答案

使用递归,你应该记住返回 1 种类型的值,然而你想要返回一个布尔值,但你希望你的函数也返回计数.这确实让事情复杂化了.

With recursion, you should remember to return 1 type of value, however you want to return a boolean yet you want your function to return count too. This really complicates things.

这是一个计算元素类型的递归函数

Heres a recursive function to count the element types

function countElements(domElement, elementType) {
    count = (domElement && domElement.tagName === elementType.toUpperCase());

    if (domElement.hasChildNodes()) {
      for (var i = 0; i < domElement.childNodes.length; i++) {
        count += countElements(domElement.childNodes[i], elementType); 
      };
    };

    return count;
}

你可以像这样使用它来实现你想要的.

you can use it like this to achieve what you want.

countElements(document, 'div') >= 5

然而,这可能不是最有效的方法,因为它会遍历整个 DOM 树,但您真正想要的是它在您点击 5 个元素时停止.

However, this might not be the most efficient way of doing it since it will traverse the whole DOM tree but what you really want is for it to stop when you've hit 5 elements.

function containsFiveOrMoreDivsPureRecursion(domElement, elementType) {
    var count = 0;

    function countElements(domElement, elementType) {
        count += (domElement && domElement.tagName === elementType.toUpperCase());

        if (count >= 5) return count;

        if (domElement.hasChildNodes()) {
          for (var i = 0; i < domElement.childNodes.length; i++) {
            countElements(domElement.childNodes[i], elementType); 
          };
        };

        return count;
    }


    return countElements(domElement, elementType) >= 5;
}

在这个例子中,你需要在你的函数之外保留一个变量(因此它不是真正的纯递归)来跟踪计数并能够返回一个布尔值.

In this example, you will need to keep a variable outside of your function (thus it's not really a pure recursion) to keep track of the count and be able to return a boolean.

这篇关于重构工作递归代码 (hasFiveDIVs) 以遍历 DOM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆