@oriol为我今天正在处理的问题提供了一个惊人的两行递归解决方案。
function numOccurencesRecursive(arr, val) {
if (!arr.length) return 0;
return (arr[0] === val ? 1 : 0) + numOccurencesRecursive(arr.slice(1), val);
}
我受到启发,重构了我昨天写的一些spagetti-ish代码:
//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()); //?
}
如何在此版本中递归遍历所有子节点?我正在做什么?
答案 0 :(得分:0)
使用递归,你应该记得返回1种类型的值,但是你想要返回一个布尔值但是你希望你的函数也返回计数。这确实使事情复杂化。
这是一个递归函数来计算元素类型
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;
}
你可以像这样使用它来达到你想要的效果。
countElements(document, 'div') >= 5
但是,这可能不是最有效的方法,因为它会遍历整个DOM树,但你真正想要的是它在你击中5个元素时停止。
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;
}
在这个例子中,你需要在函数之外保留一个变量(因此它不是真正的纯递归)来跟踪计数并能够返回一个布尔值。