为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

胡说叔叔 2019-12-12 14:10:20
情况:我有一个包含多个子对象和子子对象的大对象,其属性包含多个数据类型。为了我们的目的,该对象看起来像这样:var object = {    aProperty: {        aSetting1: 1,        aSetting2: 2,        aSetting3: 3,        aSetting4: 4,        aSetting5: 5    },    bProperty: {        bSetting1: {            bPropertySubSetting : true        },        bSetting2: "bString"    },    cProperty: {        cSetting: "cString"    }}我需要遍历此对象并构建一个显示层次结构的键的列表,因此该列表最终看起来像这样:aProperty.aSetting1aProperty.aSetting2aProperty.aSetting3aProperty.aSetting4aProperty.aSetting5bProperty.bSetting1.bPropertySubSettingbProperty.bSetting2cProperty.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/
查看完整描述

3 回答

?
撒科打诨

TA贡献1934条经验 获得超2个赞

我为你做了一个情人。我存储一个stack字符串,然后输出,如果该属性是原始类型的:


function iterate(obj, stack) {

        for (var property in obj) {

            if (obj.hasOwnProperty(property)) {

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

                    iterate(obj[property], stack + '.' + property);

                } else {

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

                    $('#output').append($("<div/>").text(stack + '.' + property))

                }

            }

        }

    }


iterate(object, '')

不要使用,它已被窃听?

我最近在这个问题上获得了很多好评,因此我决定使用一些ES2015 +魔术和更多功能的样式来完善该解决方案。


它可能不太可读,但是我喜欢它的外观:)您仍然可以从上面使用一个更简单的解决方案-两者应该完全一样。


const isObject = val =>

  typeof val === 'object' && !Array.isArray(val);


const paths = (obj = {}) =>

  Object.entries(obj)

    .reduce(

      (product, [key, value]) =>

        isObject(value) ?

        product.concat([

          [key, paths(value)] // adds [root, [children]] list

        ]) :

        product.concat([key]), // adds [child] list

      []

    )


const addDelimiter = (a, b) =>

  a ? `${a}.${b}` : b;


const pathToString = ([root, children]) =>

  children.map(

    child =>

      Array.isArray(child) ?

      addDelimiter(root, pathToString(child)) :

      addDelimiter(root, child)

  )

  .join('\n');


const input = {

  aProperty: {

    aSetting1: 1,

    aSetting2: 2,

    aSetting3: 3,

    aSetting4: 4,

    aSetting5: 5

  },

  bProperty: {

    bSetting1: {

      bPropertySubSetting: true

    },

    bSetting2: "bString"

  },

  cProperty: {

    cSetting: "cString"

  }

};


// ^ implies a "root" level will be ["", paths(input)]

// ideally paths() should return that structure, but I could not figure out how :)

// shows desired output format

console.log(pathToString(["", paths(input)]));


// showcase the resulting data structure

// any object can be recursively represented as a list [objectPropertyName, [...nestedPropertyNames]]

// console.log(paths(input));



查看完整回答
反对 回复 2019-12-13
  • 3 回答
  • 0 关注
  • 322 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号