如何检测JavaScript对象的深度

时间:2015-05-18 23:24:05

标签: javascript

我有一个JSON文件,它被加载到我的JavaScript中并转换为一个对象。然后根据我需要显示的内容来获取此对象的部分,因此所使用的对象部分是动态的。

大多数情况下,使用的部件看起来像:

"Values": {
    "Var1": "Val1",
    "Var2": "Val2",
    "Var3": "Val3"
}

但在极少数情况下,有多个集合,如:

"Values": {
    "Set1": {
        "Var1": "Val1",
        "Var2": "Val2",
        "Var3": "Val3"
    },
    "Set2": {
        "Var1": "Val1",
        "Var2": "Val2",
        "Var3": "Val3"
    }
}

出于渲染目的,我需要检测Values是否有子集。每个值/集中“VarX”的数量可能会有所不同,因此依靠它是不切实际的。同样,“SetX”的名称也不一致。

第一个变量虽然应该始终为Var1,但由于无法保证这样的对象的顺序,这也不是一个令人满意的解决方案。

我认为理想的解决方案是检测物体的尺寸,并从那里开始。我已经尝试过在线和SO上描述的各种方法,但它们似乎只计算有多少总键/值,而不是尺寸。

2 个答案:

答案 0 :(得分:2)

您可以循环检查手头的属性是否为对象:

function isObject (item) {
  return (typeof item === "object" && !Array.isArray(item) && item !== null);
}

使用这样的函数,你可以递归迭代,直到你击中一个字符串。

var maxDepth = 0;

var recurse = function(depth) {
  depth = depth || 0;
  depth++;
  maxDepth = (depth) > maxDepth ? depth : maxDepth;
  for (var item in blob) {
    if (blob.hasOwnProperty(item)) {
      if (!isObject(blob[item]) {
        // .. the buck stops here
      } else {
        depth++;
        recurse(depth);
      }
    }
  }
}
recurse(0);

你可以建立这个基本功能,但这应该让你基本了解我的意思。

答案 1 :(得分:1)

这是一个函数,它将检查一个简单对象的最大深度:

function getDepth (obj) {
    var _index = 0,
        _loop  = function (o) {
            var _childIndex = false,
                _keys       = Object.keys(o);
            _index += 1;
            for (var i in o) {
                if (o[i].toString() == '[object Object]') {
                    _childIndex = i;
                }
                if (_childIndex !== false && i === _keys.reverse()[0]) {
                    _loop(o[i]);
                }
            }
        };
    _loop(obj);
    return _index;
}

示例:

getDepth({
  "Values": {
     "Set1": {
        "Var1": "Val1",
        "Var2": "Val2",
        "Var3": "Val3"
     },
     "Set2": {
        "Var1": "Val1",
        "Var2": "Val2",
        "Var3": "Val3"
     },
    }
});
  

2

getDepth({
  "Values": {
     "Set1": {
        "Var1": "Val1",
        "Var2": "Val2",
        "Var3": "Val3"
     }
    }
});

Cheaty Way

这会计算{之前}的数量。更简单的解决方案:

JSON.stringify(myObject)
    .replace(/(["'])((?:(?=(?:(\\))*)\3.|.)*?)\1/g, '')
    .match(/^((?:\{[^}]*)+)/)[1]
    .split("{").length - 1;

<强>解释

JSON.stringify()将对象转换为字符串。 .replace使用我制作的RegEx,它将取出所有字符串。这适用于所有个案,并支持转义。 .match()将匹配所有{,直到第一个}split用于衡量返回的

的长度