我在javascript中编写递归函数时遇到了一些困难。我希望函数获取列表项<li>
并创建一个包含所有<li
个孩子<li>
的扁平数组。当我添加递归以便它会在多个级别找到子级时,函数似乎尽可能地在一个分支上运行,然后退出而不返回到for循环。
请参阅下面的代码和以下jsFiddle: https://jsfiddle.net/jsjxn3ym/1/
var result = [];
function flattenList(element){
childrenLevel = element.getElementsByTagName('ul').length > 0 ? Array.prototype.slice.call(element.getElementsByTagName('ul')[0].children) : undefined;
if (childrenLevel != undefined){
result = result.concat(childrenLevel);
for (var u = 0, l = childrenLevel.length; u < l; u++) {
return flattenList(childrenLevel[u]);
}
}
if (result.length === 0){
return undefined;
}
else{
return result;
}
}
var startingElement = document.getElementById('startingElement');
var functionResult = flattenList(startingElement);
答案 0 :(得分:0)
你应该简化你的循环。像这样工作:
years = rawdata(:,yearcolumn); %extracts year vector from data
rows_to_keep = years>=firstyear_i&years<maxyear; %rows we are considering
levels = [years,rawdata(:,datacolumn)]; %new vector where first column shows if being considered and second is rawdata for that row
indices1 = find(levels(:,1)==0); %indexes rows for deletion
indices2 = find(levels(:,1)==1); %indexes rows we are using
levels(indices2,1) = rawdata(indices2,1); %if using row, replace "1" with appropriate year from rawdata
levels(indices1,:) = []; %if not using row, remove it from data we are considering
希望它有所帮助。
答案 1 :(得分:0)
使用您的标记,您可以这样做。复杂性低很多
const result = Array.from(document.querySelectorAll('ul li span')).map(span => span.innerHTML);
//["A", "A1", "A2", "B", "B1", "B2"]
console.log(result);
答案 2 :(得分:0)
您的问题是您使用全局变量的事实。当你再次调用该函数时,你会在变量中写入值,这样就会导致循环退出,因为第二次调用时第一次迭代的变量不再是。
function flattenList(element){
childrenLevel = element <-- childrenLevel is a global variable
您的代码的其他问题是您在循环内部返回时。你正在更换阵列。
var result = [];
function flattenList(element) {
//you need to use var
var childrenLevel = element.getElementsByTagName('ul').length > 0 ? Array.prototype.slice.call(element.getElementsByTagName('ul')[0].children) : undefined;
if (childrenLevel != undefined) {
console.log(childrenLevel)
//no not replace the array, append to it
result.push.apply(result, childrenLevel)
for (var u = 0, l = childrenLevel.length; u < l; u++) {
flattenList(childrenLevel[u]); //do not return here
}
}
if (result.length === 0) {
return undefined;
} else {
return result;
}
}
声明变量时使用var
。或者,如果您使用的是ES6,请使用let
和const
。您的代码的另一个问题是,每次要使用该函数时,您需要手动重置result
。
现在不确定为什么你不只是从一开始就选择所有的lis而不是必须遍历它们。
const lis = document.querySelectorAll('#startingElement li span')
const txt = Array.from(lis).map(o => o.textContent).join(', ')
document.getElementById('log').innerHTML = txt
&#13;
<ul>
<li id="startingElement">
<ul>
<li>
<span>A</span>
<ul>
<li><span>A1</span></li>
<li><span>A2</span></li>
</ul>
</li>
<li>
<span>B</span>
<ul>
<li><span>B1</span></li>
<li><span>B2</span></li>
</ul>
</li>
</ul>
</li>
</ul>
<div id="log">
<h2>Log:</h2>
</div>
&#13;