2013-07-06 1 views
5

следущие Например: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 показывая его использование, а также (для обеспечения он действительно работал на моем правде небольшого набора образцов).

+0

Удивительный! Вам не нужно возвращать объект. Если я изменю это, это будет работать так, как ожидалось. Или я что-то путаю? –

+0

@ChristopherWill Не путайте ничего. Я забыл скопировать его из примера JS Fiddle. Единственное, что нужно отметить, это немного отличается от желаемой функциональности тем, что вы должны явно указывать каждое имя свойства (например, '' example "' и '" address.example "'). Это более строгий белый список, но его проще реализовать. – pickypg

+0

Мне действительно нравится этот подход, это именно то, что я искал. –

2

Вы можете добавить метод 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/

+0

К сожалению, это не решение для меня, потому что белый список основан на контексте (и объекты JSON фактически преобразуются в объекты мангуста). –

+0

Есть еще одно решение, теперь я тестирую его в jsfiddle. Я добавлю это через несколько минут. –

+0

Обновлен мой ответ, но слишком поздно :) –