JS递归查找对象数组的某个值?

代码如下

任意给一个对对象或者数组,通过遍历,递归查找其中是否存在某个值,
代码我已经写的差不多了,但是只支持单次查找。
因为flag重置问题没法解决。
如果在函数体最后if里面,flag= false,则涉及到对象中的数组的时候就不起作用了。因为if(flag)虽然执行了
但是**并没有跳出递归。**

所以我的问题就是怎么正确重置flag~
希望有朋友能够解惑~_**

<script type="text/javascript">
    var flag = false;
    function exitindata(data,item){
    if(data instanceof Array){
         var i = data.length;
         while(i--){
            if(flag){
                break;
            }
            if(data[i] === item){
                flag = true;
                break
            }else{
                if(data[i] instanceof Array || data[i] instanceof Object){
                         exitindata(data[i],item);
                    }
            }
         }
    }else{
        for(var key in data){
            if(flag){   
                break
            }
            if(data.hasOwnProperty(key) === true){
                 if(data[key]  === item){
                    flag = true;
                    break
                 }else{
                    if(data[key] instanceof Array || data[key] instanceof Object){
                         exitindata(data[key],item);
                    }
                 }
            }
        }
    }
    if(flag){
        return true;
    }else{
        return null
    }
} 
function find(item){
    var data = [9,
    {
        item1:50,
        item2:94,
        item3:[
            {
                cc: 9999,
                ff:9090
            }
        ]
    }
    ,65,1111,54,11,0,1,3,7,8,5,649,841];
    console.log(exitindata(data,item));
}
find(9090)
find(9091)
find(9999)
</script>

单次查找没问题。
多次就出问题啦

之前回答感觉都好乱,再来一次吧。楼主程序里面是有递归终止条件的,并不是没有。没看到的可以仔细看看。
题主:你在exitindata函数中递归调用自身的时候,它有返回的值的,你用flag接住就可以了。同时,最后判断flag时,如果flag为true,要将flag重置为false,为下一次查找调用初始化flag

 <script type="text/javascript">
    var flag = false;
    function exitindata(data,item){
    if(data instanceof Array){
         var i = data.length;
         while(i--){
            if(flag){
                break;
            }
            if(data[i] === item){
                flag = true;
                break
            }else{
                if(data[i] instanceof Array || data[i] instanceof Object){
                         //此时用flag接住,如果递归找到,flag为true,否则为null
                                                flag=exitindata(data[i],item);
                    }
            }
         }
    }else{
        for(var key in data){
            if(flag){   
                break
            }
            if(data.hasOwnProperty(key) === true){
                 if(data[key]  === item){
                    flag = true;
                    break
                 }else{
                    if(data[key] instanceof Array || data[key] instanceof Object){
                         //此时用flag接住,如果递归找到,flag为true,否则为null
                                                flag=exitindata(data[key],item);
                    }
                 }
            }
        }
    }
    if(flag){
        //重置flag,为下次查找初始化flag
        flag=false;
        return true;
    }else{
        return null
    }
} 
function find(item){
    var data = [9,
    {
        item1:50,
        item2:94,
        item3:[
            {
                cc: 9999,
                ff:9090
            }
        ]
    }
    ,65,1111,54,11,0,1,3,7,8,5,649,841];
    console.log(exitindata(data,item));
}
</script>

public static long fac(int n){
//递归头,如果没有递归头,递归函数将陷入死循环
if(n==1){
return 1;
}else{//递归体
return n*fac(n-1);
}

}
//正在学java 没学js,但愿对你有帮助。我看你if  或else 中都在调用 自己,这样肯定有问题。

题主:你在exitindata函数中递归调用自身的时候,它有返回的值的,你用flag接住就可以了。同时,最后判断flag时,如果flag为true,要将flag重置为false。
代码改动如下:
<br> var flag = false;<br> function exitindata(data,item){<br> if(data instanceof Array){<br> var i = data.length;<br> while(i--){<br> if(flag){<br> break;<br> }<br> if(data[i] === item){<br> flag = true;<br> break<br> }else{<br> if(data[i] instanceof Array || data[i] instanceof Object){<br> //此时用flag接住,如果递归找到,flag为true,否则为null<br> ** flag=exitindata(data[i],item);**<br> }<br> }<br> }<br> }else{<br> for(var key in data){<br> if(flag){<br><br> break<br> }<br> if(data.hasOwnProperty(key) === true){<br> if(data[key] === item){<br> flag = true;<br> break<br> }else{<br> if(data[key] instanceof Array || data[key] instanceof Object){<br> //此时用flag接住,如果递归找到,flag为true,否则为null <br> ** flag=exitindata(data[key],item);**<br> }<br> }<br> }<br> }<br> }<br> if(flag){<br> //如果找到了,要把flag置为false,为下次查找初始化flag<br> ** flag=false;**<br> return true;<br> }else{<br> return null<br> }<br> } <br> function find(item){<br> var data = [9,<br> {<br> item1:50,<br> item2:94,<br> item3:[<br> {<br> cc: 9999,<br> ff:9090<br> }<br> ]<br> }<br> ,65,1111,54,11,0,1,3,7,8,5,649,841];<br> console.log(exitindata(data,item));<br> }</p> <p>我测试了之后是可以多次查找的<br> 不知是不是你想要的结果。如有不对,望指正。</p>

递归,是以本方法的返回值为基础的。函数结束或不结束都在等,你递归头的值,如果没有递归头的值,你前面调用自身的函数会一直等待。不知道,
js里面有没集合,如果有,你把你要处理的数据,全丢集合里面。比如
Map mp=new HashMap();
mp.put(1, 123);
mp.put("111", 456);

System.out.println(mp.containsKey("111"));

为什么不把 var flag = false; 放在函数内?

flag = true; 的位置为什么不直接 return true; ???
var flag = false; 放在函数外,每次执行 Find 的时候,都需要重新初始化 flag = false;

给你改完了,这个可以用

var flag = false;
    function exitindata(data,item){
    if(data instanceof Array){
         var i = data.length;
         while(i--){
            if(flag){
                break;
            }
            if(data[i] === item){
                flag = true;
                break
            }else{
                if(data[i] instanceof Array || data[i] instanceof Object){
                        flag=exitindata(data[i],item);
                    }
            }
         }
    }else{
        for(var key in data){
            if(flag){   
                break
            }
            if(data.hasOwnProperty(key) === true){
                 if(data[key]  === item){
                    flag = true;
                    break
                 }else{
                    if(data[key] instanceof Array || data[key] instanceof Object){
                         flag=exitindata(data[key],item);
                    }
                 }
            }
        }
    }
    if(flag){
        flag=false;   return true;
    }else{
        return null
    }
} 
function find(item){
    var data = [9,
    {
        item1:50,
        item2:94,
        item3:[
            {
                cc: 9999,
                ff:9090
            }
        ]
    }
    ,65,1111,54,11,0,1,3,7,8,5,649,841];
    console.log(exitindata(data,item));
} 

/** 通用的treeData递归查找某一项
 * @origin 原始数据默认[]
 * @childrenName children字段名称默认children
 * @fieldName 对比的字段名称默认id
 * @value 需要对比的值默认为空字符串
 */
export function TreeDataFindItem({
  origin = [],
  childrenName = 'children',
  fieldName = 'id',
  value = '',
}) {
  let item = null
  function loop(arr) {
    for (let i = 0; i < arr.length; i++) {
      const x = arr[i]
      if (x[fieldName] === value) {
        item = x
        break
      }
      if (Array.isArray(x[childrenName])) {
        loop(x[childrenName])
      }
    }
  }
  loop(origin)
  if (item) return item
  return null
}