Белый список JSON.stringify с вложенными объектами
Приведен следующий пример:
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']));
Как я могу использовать функцию stringify JSON для правильной работы с вложенными объектами?
Поскольку у меня огромные объекты JSON, случается, что ключ вложенного объекта идентичен его "родительскому" объекту. Я хотел бы указать мой белый список более гранулированный.
2 ответа
Если вы готовы заняться созданием белого списка, вы можете создать массив допустимых ключей, которые могут обеспечить возможность вложения, аналогичного тому, сколько систем выполняет вложение 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, показывающий его использование (чтобы убедиться, что он действительно работает на моем, по общему признанию, небольшом семпле).
Вы можете добавить метод toJSON в ваши огромные объекты 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"}}"
Проверьте jsfiddle http://jsfiddle.net/SaKhG/