递归遍历对象以建立属性列表

情况:我有一个包含多个子对象和子子对象的大对象,其属性包含多个数据类型。为了我们的目的,该对象看起来像这样:


var object = {

    aProperty: {

        aSetting1: 1,

        aSetting2: 2,

        aSetting3: 3,

        aSetting4: 4,

        aSetting5: 5

    },

    bProperty: {

        bSetting1: {

            bPropertySubSetting : true

        },

        bSetting2: "bString"

    },

    cProperty: {

        cSetting: "cString"

    }

}

我需要遍历此对象并构建一个显示层次结构的键的列表,因此该列表最终看起来像这样:


aProperty.aSetting1

aProperty.aSetting2

aProperty.aSetting3

aProperty.aSetting4

aProperty.aSetting5

bProperty.bSetting1.bPropertySubSetting

bProperty.bSetting2

cProperty.cSetting

我有这个函数,它确实遍历对象并吐出键,但不是分层地:


function iterate(obj) {

    for (var property in obj) {

        if (obj.hasOwnProperty(property)) {

            if (typeof obj[property] == "object") {

                iterate(obj[property]);

            }

            else {

                console.log(property + "   " + obj[property]);

            }

        }

    }

}

有人可以让我知道该怎么做吗?这是一个让您迷惑的jsfiddle:http : //jsfiddle.net/tbynA/


胡说叔叔
浏览 323回答 3
3回答

撒科打诨

我为你做了一个情人。我存储一个stack字符串,然后输出,如果该属性是原始类型的:function iterate(obj, stack) {&nbsp; &nbsp; &nbsp; &nbsp; for (var property in obj) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (obj.hasOwnProperty(property)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (typeof obj[property] == "object") {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; iterate(obj[property], stack + '.' + property);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(property + "&nbsp; &nbsp;" + obj[property]);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $('#output').append($("<div/>").text(stack + '.' + property))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }iterate(object, '')不要使用,它已被窃听我最近在这个问题上获得了很多好评,因此我决定使用一些ES2015 +魔术和更多功能的样式来完善该解决方案。它可能不太可读,但是我喜欢它的外观:)您仍然可以从上面使用一个更简单的解决方案-两者应该完全一样。const isObject = val =>&nbsp; typeof val === 'object' && !Array.isArray(val);const paths = (obj = {}) =>&nbsp; Object.entries(obj)&nbsp; &nbsp; .reduce(&nbsp; &nbsp; &nbsp; (product, [key, value]) =>&nbsp; &nbsp; &nbsp; &nbsp; isObject(value) ?&nbsp; &nbsp; &nbsp; &nbsp; product.concat([&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [key, paths(value)] // adds [root, [children]] list&nbsp; &nbsp; &nbsp; &nbsp; ]) :&nbsp; &nbsp; &nbsp; &nbsp; product.concat([key]), // adds [child] list&nbsp; &nbsp; &nbsp; []&nbsp; &nbsp; )const addDelimiter = (a, b) =>&nbsp; a ? `${a}.${b}` : b;const pathToString = ([root, children]) =>&nbsp; children.map(&nbsp; &nbsp; child =>&nbsp; &nbsp; &nbsp; Array.isArray(child) ?&nbsp; &nbsp; &nbsp; addDelimiter(root, pathToString(child)) :&nbsp; &nbsp; &nbsp; addDelimiter(root, child)&nbsp; )&nbsp; .join('\n');const input = {&nbsp; aProperty: {&nbsp; &nbsp; aSetting1: 1,&nbsp; &nbsp; aSetting2: 2,&nbsp; &nbsp; aSetting3: 3,&nbsp; &nbsp; aSetting4: 4,&nbsp; &nbsp; aSetting5: 5&nbsp; },&nbsp; bProperty: {&nbsp; &nbsp; bSetting1: {&nbsp; &nbsp; &nbsp; bPropertySubSetting: true&nbsp; &nbsp; },&nbsp; &nbsp; bSetting2: "bString"&nbsp; },&nbsp; cProperty: {&nbsp; &nbsp; cSetting: "cString"&nbsp; }};// ^ implies a "root" level will be ["", paths(input)]// ideally paths() should return that structure, but I could not figure out how :)// shows desired output formatconsole.log(pathToString(["", paths(input)]));// showcase the resulting data structure// any object can be recursively represented as a list [objectPropertyName, [...nestedPropertyNames]]// console.log(paths(input));
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript