操纵JSON树结构

时间:2016-02-08 04:47:39

标签: javascript arrays json object

我正在构建一个表单构建器,它允许用户有多个问题,子问题,以及子问题的子问题等。

我有一种方法可以提取数据,但为此,数据/ json tree需要采用特定的格式:

u1fsQExd1aZmnpL : {
    subfields : {
        2FNdVdkaefaD6xQ : {
            subfields : {
                fZ0zn6d51TgVqID : {
                    subfields : {
                        05E1JSFYVHJlGVP : {
                            subfields : {}
                        }
                    }
                }
            }
        }
    }
}

这就是数据的开始方式:

u1fsQExd1aZmnpL : {
    2FNdVdkaefaD6xQ : {
        fZ0zn6d51TgVqID : {
            05E1JSFYVHJlGVP : {}
        }
    }
}

每个级别可以有多个项目,例如:

u1fsQExd1aZmnpL : {
    2fhjsnNchSJowl2 : {},
    2FNdVdkaefaD6xQ : {
        fZ0zn6d51TgVqID : {
            05E1JSFYVHJlGVP : {},
            03jshviJSONDJla : {}
        }
    }
}

我将数据操作到subfields表单结构的方法:

function get_into_subfields(form_structure) {
    for(var mainid in form_structure) {
        for(var key in form_structure[mainid]) {
            if(!form_structure[mainid].hasOwnProperty('subfields')) {
                form_structure[mainid]['subfields'] = {};
            }
            if(key != 'title' && key != 'placeholder' && key != 'help' && key != 'type') {
                // || {} so that the key does not have a 'undefined' value which throws an error with the extract_data method
                form_structure[mainid]['subfields'][key] = get_into_subfields(form_structure[mainid][key]) || {};

                // taking it out keeps the chain going, but it does not put it in the subfields key then
                delete(form_structure[mainid][key]);
            }
        }
    }
}   

但是,这会在第一个subfields级别上断。

u1fsQExd1aZmnpL : {
    subfields : {
        2FNdVdkaefaD6xQ : {}
    }
}

为了概述表单的外观,下面是一张图片,上面有几个注释,供您查看格式。

form structure

注意:

  • 每个问题都有一个main_id字段,其中包含唯一的ID (我忘记将屏幕截图中的My ID更改为前两个Main ID。抱歉。)
  • 每个问题都使用original_id数据属性引用第一个父级。 (主要问题)
  • 每个问题都使用parent_id数据属性引用它的特定父级。

我需要做什么: 完成格式

u1fsQExd1aZmnpL : {
    subfields : {
        2FNdVdkaefaD6xQ : {}
    }
}

并将其格式化为

u1fsQExd1aZmnpL : {
    subfields : {
        2FNdVdkaefaD6xQ : {
            subfields : {
                fZ0zn6d51TgVqID : {
                    subfields : {
                        05E1JSFYVHJlGVP : {
                            subfields : {}
                        }
                    }
                }
            }
        }
    }
}

如何更改get_into_subfields方法?

1 个答案:

答案 0 :(得分:0)

这个答案基本上用{key: value}替换任何{key: {subfields: value}},通过相同的算法递归发送value,直到所有属性级别都被处理完毕。

var data = { "u1fsQExd1aZmnpL" : { "2fhjsnNchSJowl2" : {}, "2FNdVdkaefaD6xQ" : { "fZ0zn6d51TgVqID" : { "05E1JSFYVHJlGVP" : {}, "03jshviJSONDJla" : {} } } } };

// this is main object-restructuring function
function get_into_subfields(form_structure) {
    for (var key in form_structure) {
        form_structure[key] = {subfields: get_into_subfields(form_structure[key])};
    }
    return form_structure;
}

// this function is simply for showing the code in action
// here on Stack Overflow and isn't relevant to the problem
function formatObjForHtml(obj) {
  document.write("<pre>" + JSON.stringify(obj, null, 2) + "</pre>");
}

formatObjForHtml(data);   // view the data before processing
get_into_subfields(data); // process the data
formatObjForHtml(data);   // view the data after processing

请注意,此答案中Javascript代码中原始数据的属性键显式放在引号中,因为其中一些以数字开头。如果您从JSON接收数据,这可能与您的最终申请无关。但是,在包含硬编码数据的概念验证代码中,引号是必需的。

我没有包含任何处理您在问题中讨论的“title”,“placeholder”,“main_id”等的代码。从您的问题中不清楚这些问题对于您要问的主要问题是否真正重要,即重新构建数据对象。

另请注意,此答案会改变原始data对象,而不是创建新的已修改对象。如果您希望原始数据保持不变,则首先对数据进行深度克隆,然后运行get_into_subfields(clone_of_data)

这个答案让您可以根据需要进行任何JSON转换。此答案中的JSON字符串化只是为了在Stack Overflow代码段查看器中查看结果。