3

我有以下 JSON,其中包含其他“部分”对象和“项目”的“部分”对象。从这个对象中,我需要提取“项目”字段名称(所有父部分及其名称属性的连接)及其值。这样做的有效方法是什么?

请注意,以下只是我的 json 的一部分。部分和项目的嵌套级别是无限的。我需要递归地做一些事情。

JSON:

{
    "section": [
        {
            "fieldId": "t1",
            "name": "section-1",
            "section": [
                {
                    "fieldId": "t-1",
                    "name": "section2",
                    "and": [
                        {
                            "fieldId": null,
                            "items": [
                                {
                                    "fieldId": "c-2",
                                    "name": "item1",
                                    "value": "123"
                                },
                                {
                                    "fieldId": "c-3",
                                    "name": "item2",
                                    "value": "dsadsaddsa"
                                }
                            ]
                        }
                    ],
                    "section": []
                }
            ]
        }
    ]
}

我开始写的Javascript(不完整,我卡住了):

function process(key,value) {
    if (key == "section") 
        console.log(key + " : " + JSON.stringify(value[0]));
}

function traverse(o,func) {
    for (var i in o) {
        func.apply(this,[i,o[i]]);        
        if (typeof(o[i])=="object") {
            traverse(o[i],func);
        }
    }
}

预期输出: 一个 javascript 对象

{"section1-section2-item1":123, "section1-section2-item2":"dsadsaddsa"}
4

1 回答 1

2

这是递归遍历函数的工作版本:

它很冗长,但相当有效。它确实使用默认值进行了一些额外的遍历/工作 - 如果这是一个问题,也可以清理它们。

更新以收集键/值解析,因为它们被处理并记录最终结果。

工作小提琴

// This is just to help visualize the answer in the fiddle
function log(input) {
    $('body').append($('<div>').text(input));
}

var finalObj = {};
function process(key,value) {
    log(key + " : " + value);

    // Collect in finalObj
    finalObj[key] = value;
}


function traverse(section,func,path) {
    var sectionIdx, andArr, andIdx, curAnd, items, itemIdx, curSection, curPath;

    section = section || [];
    path    = path || [];

    // Start with something in the path for this level
    path.push('');

    for(sectionIdx = 0; sectionIdx < section.length; ++sectionIdx) {
        // Set reasonable defaults for current values
        curSection = section[sectionIdx] || {};
        andArr     = curSection.and || [];

        // Update the name if the section for this level in the hierarchy
        path[path.length - 1] = curSection.name;

        // Recurse into the current section
        traverse(curSection.section, func, path);

        // Remove the last part of the path from the previous recursion
        path.length = path.length - 1;

        // Current path as a string
        curPath = path.join('-'); 

        // Now iterate all the and objects
        for(andIdx = 0; andIdx < andArr.length; ++andIdx) {
            // Setup reasonable defaults for and and items
            curAnd = andArr[andIdx] || {};
            items  = curAnd.items || [];

            // Run through the items and process them with the full path
            for(itemsIdx = 0; itemsIdx < items.length; ++itemsIdx) {
                process(curPath + '-' + items[itemsIdx].name, items[itemsIdx].value);
            }
        }
    }
}

traverse(jsonInput.section, process);

// Log out finalObj
log("Final Result:");
log(JSON.stringify(finalObj));

输出(基于name提供的 JSON 中的当前属性):

section-1-section2-item1 : 123
section-1-section2-item2 : dsadsaddsa
Final Result:
{"section-1-section2-item1":"123","section-1-section2-item2":"dsadsaddsa"}

当没有子节数组时,更新的小提琴避免了额外的递归

于 2013-08-12T18:01:04.223 回答