如何计算一个对象的深度

3,187 阅读2分钟

问题描述

给定一个对象,如下示例:

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

方案可能不足的地方

  1. 循环引用报错
var f ={}
f.d = f
console.log(getObjLevel(f)) // RangeError: Maximum call stack size exceeded

可以判断是否是循环引用,从而返回特定的值。

  1. 数组也被计算一层
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♪(・ω・)ノ