遍历json对象并根据键名将子obj属性移动到父级

时间:2014-07-09 06:28:19

标签: javascript json

我有一个JSON对象,我用它作为主题(它适用于Appcelerator,但实际上,它并不重要,因为这更像是一个JSON问题。)如果有帮助,我确实可以访问underscore.js遍历/函数......但纯JS也可以运行。

如果该键是某个值,我需要遍历JSON树并将子对象属性移动到它的父对象,如果它是另一个值的键,则还要省略该对象。这需要在JSON树的多个级别上发生。所以我需要某种递归函数。

例如,假设我需要将具有ANDROID键的子对象的所有属性移动到它的父对象,但是如果键是IOS则忽略对象和属性:< / p>

原始对象

var theme = {
    Form: {
        LabelTop: {
            backgroundColor: 'red',
            fieldBorderColor: '#cacacf',
            rowHeight: 40,
            hintText: {
                font: {
                    fontSize: 12
                },
                colorOn: '#3accf1',
                colorOff: '#cacacf',
                ANDROID: {
                    width: 200
                }
            },

        }
    },
    Modal: {
        id: 'md',
        backgroundColor: '#fff',
        IOS: {
            color: 'red'
        }
    }
};

我希望能够打出这样的话:

var newTheme = parsePlatform(theme, 'ANDROID', 'IOS');

theme是要搜索的对象,ANDROID是合并的关键,IOS是跳过的关键

通过这个例子,如果密钥是ANDROID,我正在使用子属性移动/替换父对象的所有属性,但是我没有包含父{8}的父密钥。在这个例子中,我希望输出为:

修改后的对象

IOS

注意var theme = { Form: { LabelTop: { backgroundColor: '#fff', // replaced fieldBorderColor: '#cacacf', rowHeight: 40, hintText: { font: { fontSize: 12 }, colorOn: '#3accf1', colorOff: '#cacacf', width: 200 // 'ANDROID' prop moved } } }, Modal: { // IOS removed id: 'md', backgroundColor: '#fff' } }; 没有Modal属性,因为我只查找color,而不是ANDROID

如果我知道JSON深度和硬编码,我已经能够得到我正在寻找的结果。一旦我转移到递归函数,一切都会爆炸。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

通常情况下我会问你尝试了什么,但这个问题对我来说很有趣,以下内容没有经过严格测试,但似乎可以做到这一点:

function mergeExtend(obj, merge, skip) {
    var o, o1, nObj = {};
    for (o in obj) {
        // ensure we are only checking this obj's keys
        if (obj.hasOwnProperty(o)) {
            // check if we have keys to merge
            if ((merge || []).indexOf(o) > -1) {
                // if something was defined in merge, we expect the value to be an object
                for (var o1 in obj[o]) {
                    if (obj[o].hasOwnProperty(o1)) {
                        // put child obj val under parent key
                        nObj[o1] = obj[o][o1];
                    }
                }
            // ensure we are not skipping this key
            } else if ((skip || []).indexOf(o) === -1) {
                if (typeof obj[o] === 'object') {
                    // go recursive if we are not merging and val is an object
                    nObj[o] = mergeExtend(obj[o], merge, skip);
                } else {
                    // otherwise just copy the key val over
                    nObj[o] = obj[o];
                }
            }
        }
    } 

    return nObj;
}

console.log(mergeExtend(theme, ['ANDROID'], ['IOS']));

FIDDLE