2013-07-06 8 views
5

folgende Beispiel Gegeben:JSON.stringify weißen Listen mit verschachtelten Objekten

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'])); 

Wie kann ich JSON die stringify Funktion ordnungsgemäß mit verschachtelten Objekten umgehen?

Da ich riesige JSON-Objekte habe, passiert es, dass ein Schlüssel eines verschachtelten Objekts identisch mit seinem "Eltern" -Objekt ist. Ich möchte meine Whitelist genauer spezifizieren.

Antwort

2

Wenn Sie bereit sind, sich für die Whitelisting zu entscheiden, können Sie eine Reihe gültiger Schlüssel einrichten, die eine Verschachtelung ermöglichen, ähnlich wie viele Systeme JSON verschachteln (ein . Trennzeichen oder ein beliebiges Trennzeichen von deine Wahl).

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; 
} 

Ich habe ein JSFiddle sowie seine Verwendung zeigt (es funktionierte tatsächlich auf meinem zugegebenermaßen kleinen Probensatz zu gewährleisten).

+0

Super! Sie fehlen, um das Objekt zurückzugeben. Wenn ich das entsprechend ändere, funktioniert es wie erwartet. Oder verwechsele ich etwas? –

+0

@ChristopherWill Nichts verwirrend. Ich habe vergessen, es aus dem JS Fiddle-Beispiel zu kopieren. Das einzige, was Sie beachten sollten, ist, dass es sich leicht von Ihrer gewünschten Funktionalität unterscheidet, indem Sie jeden Eigenschaftsnamen (z. B. "example" und "address.example") explizit benennen müssen. Es ist eine strengere Whitelist, aber es ist einfacher zu implementieren. – pickypg

+0

Ich mag diesen Ansatz wirklich, das ist genau das, wonach ich gesucht habe. –

2

Sie können toJSON Methode in der riesigen JSON-Objekte hinzufügen:

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 
      } 
     } 
    } 
} 

Und Sie bekommen:

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

Oder können Sie einige Filterfunktion benutzen (diese Funktion mit 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"}}" 

Check out jsfiddle http://jsfiddle.net/SaKhG/

+0

Leider ist dies keine Lösung für mich, weil die Whitelist ist kontextbasiert (und die JSON-Objekte sind tatsächlich konvertiert Mungo-Objekte). –

+0

Es gibt eine andere Lösung, jetzt teste ich es in jfiddle. Ich werde es in wenigen Minuten hinzufügen. –

+0

Meine Antwort aktualisiert, aber zu spät :) –