阿里前端2018秋招笔试题:判断JSON对象是否有环
来源:互联网 发布:淘宝送手机充值卡 编辑:程序博客网 时间:2024/05/18 03:30
前几天做了阿里前端秋招笔试题,感觉受打击很深,找工作很难呀。不过考试完还是要复盘一下。记得有一道题目是判断JSON对象是否有环。因为当使用JSON.stringify()
方法格式化一个JSON对象时,如果该对象有环路,就会抛出异常:Uncaught TypeError: Converting circular structure to JSON
。例如一下代码:
var obj={ f:{ name:'fff', age:20, call:null }}obj.f.call=obj.f;//Uncaught TypeError: Converting circular structure to JSON(…)JSON.stringify(obj)
当时考试的时候想了好长时间也写不出代码,虽然有思路,但总感觉代码很难写。所以这几天趁着有富裕时间,总算完成了代码的编写:
function isCycle(obj){ var arr=['obj'],l=1,k=0,flag=false,str=''; while(l>k){ var obj_tmp=eval(arr[k]); var all=Object.keys(obj_tmp); str=arr[k]+'.'; if(all.length>0){ for(var i=0,length=all.length;i<length;i++){ if((typeof obj_tmp[all[i]]) !='object'||Object.prototype.toString.call(obj_tmp)=='[object String]')continue; for(var j=0;j<l;j++){ if(obj_tmp[all[i]]==eval(arr[j])){ flag=true; break; } } if(flag)break; arr.push(str+all[i]); l++; } } if(flag)break; k++; } if(flag)return true; else return false;}
最终测试如下:
var obj={ f:{ name:'fff', age:20, call:null }};obj.f.call='fff';console.log(isCycle(obj));//output:false;obj.f.call=obj.f;console.log(isCycle(obj));//output:true;obj.f.call=new Date();console.log(isCycle(obj));//output:false;obj.f.call=new String('ddd');console.log(isCycle(obj));//output:false;obj.f.call=[obj.f];console.log(isCycle(obj));//output:true;
总体思想就是BFS,宽度优先搜索遍历得到对象的所有属性,维护一个数组存储遍历得到的所有值为对象的属性,在遍历一个新属性的时候首先检测其是否与属性数组中的某一项相等,若相等,则证明它是一个环,则要返回true;否则的话就将该属性放进属性数组中,继续遍历。因为属性都存在了数组里,其实遍历属性就是遍历整个属性数组,循环结束条件就是遍历完整个数组的属性。关于该方式有几点要注意:
上述思想中一个关键点是数组只保存属性值为对象的属性,因为属性值为基本类型的值不可能构成回环,只有值为对象的属性间的相互引用才能构成回环。而一些特殊的对象如基本包装类型、日期类型也不符合要求,可以通过
Object.keys(attr).length>0
过滤除去,不过对于String对象还需要进行进一步的过滤,因为显然它不会构成引用,而上面的方式也不会将其过滤除去。所以需要用Object.prototype.toString.call(obj_tmp)=='[object String]'
将其过滤。另外一个要注意的是如何判断两个属性是否相等,此时需要将属性数组里面的每个属性的值还原出来。我暂时没想到特别好的方式,用了一种效率低的方法。因为存属性用的是点号,例如
obj
、obj.f
、obj.f.call
,所以还原用到了eval()
方法,所以代码效率可能有点低,不过运行正常,也算圆了我的一大遗憾了!!!
如果您有什么好的方法,可以讨论。如有错误,请不吝指正。
- 阿里前端2018秋招笔试题:判断JSON对象是否有环
- 阿里校招前端笔试题小结
- 阿里校招前端笔试题小结
- 2017秋招阿里笔试题--组队
- 阿里2018校招笔试编程题
- 京东2018秋招前端笔试编程题
- 阿里巴巴2017秋招前端笔试题
- 百度前端秋招笔试编程题
- 阿里前端笔试题
- 阿里前端笔试题
- 阿里校招笔试题
- 2015 阿里校招 Web前端开发 在线笔试总结
- 阿里2018秋招模拟笔试Java研发岗试题
- 阿里秋招在线笔试两道编程题
- 阿里2018校招客户端研发笔试之编程题
- [阿里] 判断单链表是否有环 以及 环的位置
- 笔试题:判断一个单链表是否有环,如果有,找出环的起始位置
- 2015阿里秋招在线笔试
- HDU6181 Two Paths(次短路,路径记录,spfa,2017 HDU多校联赛 第10场)
- 关于ui-view最佳实践的疑惑
- C# Redis消息队列例子
- 事务处理的四大特性详解
- ORM(1)转载
- 阿里前端2018秋招笔试题:判断JSON对象是否有环
- Lua中function的几种赋值方法
- JZOJ2017.08.12 B组
- 数组只能在初始化时整体赋初值。以后再赋值只能逐一改变了
- 算法与数据结构-队列的基本操作C语言实现
- docker 官网 出现技术故障
- 【服务器】服务器上设置定时任务,定时执行Java程序
- JS中的计算其中的一些对应的长度
- get和post的区别