递归JavaScript在第一次传递后返回
Recursive JavaScript returning after first pass
我有下面的递归javascript函数,它在主干的子级上循环。rionette CollectionView有子级ItemViews,而ItemViews又是CollectionViews:
findViewByCid: function(cid, children){
var col = (arguments.length === 1) ? this.children : children;
if(cid in col){
return col[cid];
}
for(child in col){
var grandChildren = col[child].children;
if(cid in grandChildren){
return grandChildren[cid];
}
if(grandChildren && (!jQuery.isEmptyObject(grandChildren))){
return this.findViewByCid(cid, grandChildren);
}
}
}
我这样称呼它:
var view=DocumentManager.Documents.treeRoot.findViewByCid(model.cid);
问题在于线路:
return this.findViewByCid(cid, grandChildren);
如果我有一个像这样的层次结构
c1
|_c2
|_c3
|_c4
|_c5
然后te return语句将导致函数在通过th3 c2节点后退出,并且永远不会到达c4等。
如果删除return语句,则会找到正确的子项,但返回null。
如何继续解析层次结构并返回值?
返回将退出您的函数。
尝试将所有内容保存在var中,在最后返回,如果需要返回多个值,它可以是一个数组。(不要在for循环中声明vars!)
以下是建议:
findViewByCid: function(cid, children){
var willBeReturned=[];
var grandChildren;
var col = (arguments.length === 1) ? this.children : children;
if(cid in col){
willBeReturned[willBeReturned.length] = col[cid];
}
for(child in col){
grandChildren = col[child].children;
if(cid in grandChildren){
willBeReturned[willBeReturned.length] = grandChildren[cid];
}
if(grandChildren && (!jQuery.isEmptyObject(grandChildren))){
willBeReturned[willBeReturned.length] = this.findViewByCid(cid, grandChildren);
}
}
return willBeReturned;
}
只有在找到内容时才需要返回,否则return
语句将在不搜索其他子项的情况下中断循环。这是一个简单的深度优先搜索你想要什么。
假设函数在每个子节点的原型上(不仅在根节点上):
findViewByCid: function(cid) {
var col = this.children;
if (!col) // break if the node has no children
return false;
if (cid in col) // look for cid and return the node if one found
return col[cid];
for (var child in col) {
// search through each child and return the result if something is found
var found = col[child].findViewByCid(cid);
if (found)
return found;
}
// else nothing was found
return false;
}
或者有一个以节点为自变量的函数:
function findViewByCid(cid, node) {
var col = node.children;
if (!col)
return false;
if (cid in col)
return col[cid];
for (var child in col) {
var found = findViewByCid(cid, col[child]);
if (found)
return found;
}
return false;
}
然而,这种算法似乎无法找到根节点。如果您可以通过cid
识别当前节点,而不是查看它的所有子节点,那会更好:
if (this /*… is what we have searched for */)
return this;
findViewByCid: function(cid, children) {
var col = (arguments.length === 1) ? this.children : children;
if(cid in col){
return col[cid];
}
for(var childKey in col) {
var grandChildren = col[childKey].children,
childView;
if (grandChildren) {
childView = this.findViewByCid(cid, grandChildren);
}
if (childView) {
return childView;
}
}
return null;
}
首先,这看起来像Backbone.js,如果是的话,标记它可能会很有帮助。我觉得人们可能遇到过类似的问题,并且知道更好的方法来存储对视图的引用。
你只想在找到东西的时候归还。。。只要在第一个递归调用中使用return,就会在搜索第一组孙时强制该方法停止执行,即使什么都没有找到。
我还想在for循环中引入的新变量前面添加一个var——如果没有它,这个变量将是全局的。
这就是我最终得到的结果,它是backbone.rionette,用collectionView的itemView迭代collectionView:
findViewByCid: function(cid){
var self = this,
ret;
function findView(cid, children){
var col = (arguments.length === 1) ? self.children : children,
grandChildren;
if(cid in col){
ret = col[cid];
}
for(child in col){
grandChildren = col[child].children;
if(cid in grandChildren){
ret = grandChildren[cid];
}
if(grandChildren && (!jQuery.isEmptyObject(grandChildren))){
findView(cid, grandChildren);
}
}
};
findView(cid);
return ret;
}
我相信if(col中的cid)行不是你想做的。试试
findViewByCid: function(cid, children){
if (this.cid === cid) return this;
var col = (arguments.length === 1) ? this.children : children;
for(var childI in col){
var child = col[childI];
if (child.cid === cid) {
return child;
}
var grandChildren = child.children;
if(grandChildren && (!jQuery.isEmptyObject(grandChildren))){
return this.findViewByCid(cid, grandChildren);
}
}
}
- 相同的RegExp返回不同的结果-第一次是正确的结果,第二次是null
- 递归JavaScript在第一次传递后返回
- MongoDB赢得't第一次返回正确的数据
- jQuery:单击Ajax返回数据,但在第一次调用时显示在警报中
- 画布到数据URL在第一次尝试时不会返回整个URL
- 具有非全局正则表达式的“match”和“exec”似乎返回第一个匹配项两次
- JQuery Mobile JS脚本第一次运行,但返回页面时不会运行
- 在初始页面加载时启动计时器.如果他们离开和返回,必须从第一次装载开始计数
- Ajax响应总是在第一次调用后返回2
- AngularJS在第一次点击时返回undefined
- Javascript getElementsByClassName()在第一次成功执行后返回undefined
- JQuery getJson方法第一次返回缓存的数据
- 对函数的调用为什么只在第一次返回字符串,之后就没有定义?
- Javascript函数在条件调用中,如果第一次返回false,则不被调用
- Node.js, Mongoose函数第一次返回错误,第二次不返回
- Twitter更新在QML中运行时返回401 Unauthorized,但第一次只能在桌面Java上工作
- Angularjs $http在第一次调用ng-click后不返回调用
- Node.js/Javascript Date()命令在第一次调用后返回乱码结果
- AJAX只在第一次点击后返回数据
- 当我第一次隐藏元素时,If语句从未返回true