首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >递归地循环遍历对象以构建属性列表

递归地循环遍历对象以构建属性列表
EN

Stack Overflow用户
提问于 2013-03-29 03:40:50
回答 16查看 124K关注 0票数 67

场景:我有一个包含多个子对象和子子对象的大型对象,这些对象的属性包含多种数据类型。出于我们的目的,这个对象看起来像这样:

代码语言:javascript
运行
复制
var object = {
    aProperty: {
        aSetting1: 1,
        aSetting2: 2,
        aSetting3: 3,
        aSetting4: 4,
        aSetting5: 5
    },
    bProperty: {
        bSetting1: {
            bPropertySubSetting : true
        },
        bSetting2: "bString"
    },
    cProperty: {
        cSetting: "cString"
    }
}

我需要遍历这个对象,并构建一个显示层次结构的键的列表,因此该列表最终如下所示:

代码语言:javascript
运行
复制
aProperty.aSetting1
aProperty.aSetting2
aProperty.aSetting3
aProperty.aSetting4
aProperty.aSetting5
bProperty.bSetting1.bPropertySubSetting
bProperty.bSetting2
cProperty.cSetting

我得到了这个函数,它循环遍历对象并输出键,但不是分层的:

代码语言:javascript
运行
复制
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/

EN

回答 16

Stack Overflow用户

回答已采纳

发布于 2013-03-29 03:47:05

我给你做了一个。我存储了一个stack字符串,然后输出它,如果属性是原语类型的:

代码语言:javascript
运行
复制
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, '')

更新(17/01/2019) -<曾经有一个不同的实现,但它不起作用。有关更漂亮的解决方案,请参阅this answer :)>

票数 117
EN

Stack Overflow用户

发布于 2018-12-05 04:25:56

Artyom Neustroev的解决方案不适用于复杂的对象,因此这里有一个基于他的想法的有效解决方案:

代码语言:javascript
运行
复制
function propertiesToArray(obj) {
    const isObject = val =>
        typeof val === 'object' && !Array.isArray(val);

    const addDelimiter = (a, b) =>
        a ? `${a}.${b}` : b;

    const paths = (obj = {}, head = '') => {
        return Object.entries(obj)
            .reduce((product, [key, value]) => 
                {
                    let fullPath = addDelimiter(head, key)
                    return isObject(value) ?
                        product.concat(paths(value, fullPath))
                    : product.concat(fullPath)
                }, []);
    }

    return paths(obj);
}
票数 60
EN

Stack Overflow用户

发布于 2016-02-11 23:01:28

如果对象在其对象图中有循环,你就会遇到问题,例如:

代码语言:javascript
运行
复制
var object = {
    aProperty: {
        aSetting1: 1
    },
};
object.ref = object;

在这种情况下,您可能希望保留已经遍历过的对象的引用&将它们排除在迭代之外。

如果对象图太深,你也会遇到问题,比如:

代码语言:javascript
运行
复制
var object = {
  a: { b: { c: { ... }} }
};

你会得到太多的递归调用错误。两者都可以避免:

代码语言:javascript
运行
复制
function iterate(obj) {
    var walked = [];
    var stack = [{obj: obj, stack: ''}];
    while(stack.length > 0)
    {
        var item = stack.pop();
        var obj = item.obj;
        for (var property in obj) {
            if (obj.hasOwnProperty(property)) {
                if (typeof obj[property] == "object") {
                  var alreadyFound = false;
                  for(var i = 0; i < walked.length; i++)
                  {
                    if (walked[i] === obj[property])
                    {
                      alreadyFound = true;
                      break;
                    }
                  }
                  if (!alreadyFound)
                  {
                    walked.push(obj[property]);
                    stack.push({obj: obj[property], stack: item.stack + '.' + property});
                  }
                }
                else
                {
                    console.log(item.stack + '.' + property + "=" + obj[property]);
                }
            }
        }
    }
}

iterate(object); 
票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15690706

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档