问题描述
给定一个对象,如下示例:
var b = {
c:1,
d:{
c:1
}
}
对象b的最大层级数是2,则该对象的深度为2。 那么如何计算一个对象的深度?
解决方案
对象的每一层可能有多个值的类型都是对象。当是对象时,要继续遍历,可以用递归实现。如果值不是对象,就把结果的值加一。
同一层,先后遍历完毕后,始终取更大的值。
function getType(param){
return Object.prototype.toString.call(param).slice(8,-1).toLowerCase()
}
function getObjLevel(obj){
if(getType(obj) !== 'object'){
throw new Error('paramater must be object')
}
// 用来保存结果,初始化层级为0
var res = 0;
function loopGetLevel(obj, level=res) {
//当前数据是不是对象,是对象就继续,否则比较下层级和值,哪个大取哪个
if (typeof obj === 'object') {
//对对象的每个属性进行遍历,如果还是对象就递归计算,否则就比较res和level取最大值
for (var key in obj) {
if (typeof obj === 'object') {
loopGetLevel(obj[key], level + 1);
} else {
// 当前层数和返回值比较取更大的
res = level + 1 > res ? level + 1 : res;
}
}
} else {
// 当前层数和返回值比较取更大的
res = level > res ? level : res;
}
}
loopGetLevel(obj)
return res
}
var a = {
b:{
c:1
}
}
console.log(getObjLevel(a)) // 2
方案可能不足的地方
- 循环引用报错
var f ={}
f.d = f
console.log(getObjLevel(f)) // RangeError: Maximum call stack size exceeded
可以判断是否是循环引用,从而返回特定的值。
- 数组也被计算一层
var e = {
a:1,
b:[5,{
c:1
}]
}
console.log(getObjLevel(e)) // 3
数组的typeof是object类型,因此也被认为是一层,可以判断数组时去掉这一层。
function getType(param){
return Object.prototype.toString.call(param).slice(8,-1).toLowerCase()
}
function getObjLevel(obj){
if(getType(obj) !== 'object'){
throw new Error('paramater must be object')
}
// 用来保存结果,初始化层级为0
var res = 0;
function loopGetLevel(obj, level=res) {
//当前数据是不是对象,是对象就继续,否则比较下层级和值,哪个大取哪个
if (typeof obj === 'object') {
//对对象的每个属性进行遍历,如果还是对象就递归计算,否则就比较res和level取最大值
for (var key in obj) {
if (typeof obj === 'object' ) {
if(Array.isArray(obj)){
loopGetLevel(obj[key], level); // 注意这里,当是数组时继续遍历,但是层数不增加
}else{
loopGetLevel(obj[key], level + 1);
}
} else {
res = level + 1 > res ? level + 1 : res;
}
}
} else {
res = level > res ? level : res;
}
}
loopGetLevel(obj)
return res
}
var e = {
a:1,
b:[5,{
c:1
}]
}
console.log(getObjLevel(e)) // 2
以上是我关于对象的深度计算的学习。如果不足,敬请指出,Thanks♪(・ω・)ノ