2014-03-07 25 views
2

通過一段JavaScript JSON對象是這樣的:JSON使用嵌套查詢字符串鍵在JavaScript

var data = { 
    blog : { 
     title: "my blog", 
     logo: "blah.jpg", 
    }, 
    posts : [ 
     { 
      title: "test post", 
      content: "<p>testing posts</p><br><p>some html</p>" 
     }, 
    ] 
} 

var lookup = "blog.title" //this gets generated from a template file 

現在我知道你可以這樣做,但這些不太做什麼,我需要:

console.log(data['blog']); //works 
console.log(data.blog.title); //works 
console.log(data['blog']['title']); //works, but i dont know the depth of the lookup 

但我需要能夠做下面的代碼,因爲我不能硬編碼結構,它會在每次查找時生成和存儲。我是否必須使用字符串切割和遞歸來構建此功能?我真的希望不要

console.log(data['blog.title']); //does not work 
console.log(data[lookup]);  //does not work 

編輯....

好吧,可能找到了解決辦法。我不知道這是安全的還是推薦的做法,所以對此的評論會很棒。或者替代方法。所以把它和上面的代碼結合起來。

var evaltest = "var asdf ="+JSON.stringify(data)+";\n" 
evaltest += "asdf."+lookup 
console.log(eval(evaltest)) //returns correctly "my blog" as expected 
+0

通過'.'分割字符串,並通過對象鍵遞歸將會做到這一點。但它必須是這種JSON的某種模式,它不能被傾銷。 – Gntem

回答

0

你可以使用:

data['blog']['title'] 
+0

我也知道這種格式。不,我不知道,因爲我不知道查找的深度。它可能最終看起來像這樣: 'var lookup =「blog.posts [342] .author.name」' – rende

1

你可以使用多蒂https://www.npmjs.org/package/dottie,它允許您遍歷深使用對象的字符串

var values = { 
    some: { 
     nested: { 
      key: 'foobar'; 
     } 
    } 
} 

dottie.get(values, 'some.nested.key'); // returns 'foobar' 
dottie.get(values, 'some.undefined.key'); // returns undefined 
+0

感謝您的這一點。它解決了問題,但同時我發現了eval()技巧,我更喜歡它,因爲它的處理依賴性較小。 – rende

+2

eval「trick」是一個非常非常糟糕的選擇。一般而言,評估是一種安全風險(從中等到極端的比例取決於輸入的控制)。 Google針對「node.js評估安全風險」。我強烈建議你不要在任何情況下使用它,並選擇專門做你需要的工具(如dottie)或自己推出。 –

0

我已經嘗試過的幾種方法這樣做包括eval和使用開關字典查找(exp.length)。這是最後的版本(註釋剝離)我創建:

var deepRead = function (data, expression) { 

    var exp = expression.split('.'), retVal; 

    do { 
     retVal = (retVal || data)[exp.shift()] || false; 
    } while (retVal !== false && exp.length); 

    return retVal || false; 

}; 

//example usage 
data = { 
    a1: { b1: "hello" }, 
    a2: { b2: { c2: "world" } } 
} 

deepRead(data, "a1.b1") => "hello" 
deepRead(data, "a2.b2.c2") => "world" 
deepRead(data, "a1.b2") => false 
deepRead(data, "a1.b2.c2.any.random.number.of.non-existant.properties") => false 

這裏是全評論主旨:gist.github.com/jeff-mccoy/9700352。我用它來循環數千個項目,並且沒有深嵌套數據的問題。另外,由於(小)性能問題,我不再打包在try/catch中:jsPerf