JavaScript中对象的多层嵌套

3
我想编写一个函数,该函数以JavaScript对象为输入,并选择对象的属性,然后返回修改后的缩进/分组结构,如下所示。
var s1 = {
    "f01":{},
    "f02":{},
    "f03":{},
    "f04":{},
    "f05":{}
};


var s2 = indent_items(s1, ["f02", "f03", "f04"]);
应该这样构建
{
    "f01":{},
    "d01":{
        "f02":{},
        "f03":{},
        "f04":{}
    },
    "f05":{}
};


var s3 = indent_items(s2, ["f03", "f04"]);

s3应该按照以下结构组织

{
    "f01":{},
    "d01":{
        "f02":{},
        "d02":{
            "f03":{},
            "f04":{}
        },
    },
    "f05":{}
};

如何实现多级嵌套?

等等更深层次的内容。

1
JavaScript 中没有内置的功能来实现这一点,您将不得不想出自己的算法,找到并替换嵌套对象中的属性。 - stack item
@Elric,f03,f04应该进一步缩进到“d03”。 - devlent
var s2 = indent_items(s1, ["f02", "f03", "f04"]); 怎么知道应该使用 d01 - Nina Scholz
1
如果出现 var s4 = indent_items(s3, ["f01", "f04"]); 会发生什么,这很有趣吧?你应该发布更多像这样的边缘情况。 - dfsq
@julestruong 我通过递归迭代输入结构,并尝试将所选属性推送到新创建的对象中,但对于多个级别来说,这很难处理。 - devlent
显示剩余4条评论
1个回答

1

这个解决方案采用递归进行缩进。

  • Object.keys 用于获取对象的所有键
  • Array.prototype.forEach 用于迭代键

function indent_items(obj, array) {

    function recursion(o, r) {
        Object.keys(o).forEach(function (k) {
            if (~array.indexOf(k)) {
                r[id] = r[id] || {};
                r[id][k] = o[k];
                return;
            }
            if (typeof o[k] === 'object') {
                r[k] = r[k] || {}
                recursion(o[k], r[k]);
                return;
            }
            r[k] = o[k];
        });
    }

    var result = {},
        id = 'd' + ('0' + ++count).slice(-2);

    recursion(obj, result);
    return result;
}

var count = 0,
    s1 = { "f01": {}, "f02": {}, "f03": {}, "f04": {}, "f05": {} },
    s2 = indent_items(s1, ["f02", "f03", "f04"]),
    s3 = indent_items(s2, ["f03", "f04"]);

document.write('<pre>s1:' + JSON.stringify(s1, 0, 4) + '</pre>');
document.write('<pre>s2:' + JSON.stringify(s2, 0, 4) + '</pre>');
document.write('<pre>s3:' + JSON.stringify(s3, 0, 4) + '</pre>');


这个 JSON.parse(JSON.stringify(obj) 可以避免吗?假设我的 f03 对象有一个 函数。在 stringifyparse 后,它会被还原到 f03 中吗? - devlent
是的,它可以。请查看编辑的内容。但是它仍然保留对旧对象的引用,而我之前通过复制对象进行了预防。 - Nina Scholz
1
太棒了!你的解决方案对我有用(稍作修改)。谢谢! - devlent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接