JSON.stringify带有嵌套对象的白名单

JSON.stringify whitelisting with nested objects

本文关键字:白名单 名单 对象 stringify 嵌套 JSON      更新时间:2023-09-26

给定以下示例:

var test = {
    "company_name": "Foobar",
    "example": "HelloWorld",
    "address": {
        "street": "My Street 12",
        "example": "BarFoo",
        "details": "Berlin",
    }
}
console.log(JSON.stringify(test, ['company_name','address','street','example']));
// What I actually want
// console.log(JSON.stringify(test, ['company_name','address.street','address.example']));

如何使用JSON的字符串函数正确处理嵌套对象?

由于我有巨大的JSON对象,所以嵌套对象的键恰好与它的"父"对象相同。我想指定我的白名单更粒度。

如果你愿意进行白名单,那么你可以建立一个有效密钥数组,它可以提供类似于多少系统进行JSON嵌套的嵌套能力(.分隔符,或你选择的任何分隔符)。

var whitelistedObj = whitelistJson(obj, ["company_name", "example", "address.street", "address.example"]);
function whitelistJson(obj, whitelist, separator) {
    var object = {};
    for (var i = 0, length = whitelist.length; i < length; ++i) {
        var k = 0,
            names = whitelist[i].split(separator || '.'),
            value = obj,
            name,
            count = names.length - 1,
            ref = object,
            exists = true;
        // fill in any empty objects from first name to end without
        //  picking up neighboring fields
        while (k < count) { // walks to n - 1
            name = names[k++];
            value = value[name];
            if (typeof value !== 'undefined') {
                if (typeof object[name] === 'undefined') {
                    ref[name] = {};
                }
                ref = ref[name];
            }
            else {
                exists = false;
                break;
            }
        }
        if (exists) {
            ref[names[count]] = value[names[count]];
        }
    }
    return object;
}

我有一个JSFiddle也展示了它的用法(以确保它在我公认的小样本集上确实有效)。

您可以在巨大的JSON对象中添加JSON方法:

var test = {
    "company_name": "Foobar",
    "example": "HelloWorld",
    "address": {
        "street": "My Street 12",
        "example": "BarFoo",
        "details": "Berlin",
    },
    toJSON: function () {
        return {
            company_name: this.company_name,
            address: {
                street: this.address.street,
                example: this.address.example
            }
        }
    }
}

而且,你会得到:

console.log(JSON.stringify(test)); // "{"company_name":"Foobar","address":{"street":"My Street 12","example":"BarFoo"}}"

或者,你可以使用一些过滤功能:(这个功能使用lodash)

function filter(object, keys, sep) {
    sep = sep || '.';
    var result = {};
    _.each(keys, function (key) {
        var keyParts = key.split(sep),
            res = object, 
            branch = {},
            branchPart = branch;
        for (var i = 0; i < keyParts.length; i++) {
            key = keyParts[i];
            if (!_.has(res, key)) {
                return;
            }
            branchPart[key] = _.isObject(res[key]) ? {} : res[key];
            branchPart = branchPart[key];
            res = res[key];
        }
        _.merge(result, branch);
    });
    return result;    
}
console.log(JSON.stringify(filter(test, ['company_name', 'address.street', 'address.example']))); // "{"company_name":"Foobar","address":{"street":"My Street 12","example":"BarFoo"}}"

查看jsfiddlehttp://jsfiddle.net/SaKhG/