簡體   English   中英

通過KeyName查找JSON數組對象值

[英]Finding JSON Array Object Values by KeyName

我正在針對以下情況在JSON中尋找一種HashMap的實現形式。

我有以下結構的JSON:

{
"level1": {
    "level2": [{
        "product1": [
            "item1",
            "item2"
        ]
    }, {
        "product2": [
            "item1",
            "item2"
        ]
    }, {
        "product3": [
            "item5",
            "item6"
        ]
    }]
}
}

對於我的用例,我得到一個值,例如“ product3”,我想找到該鍵的值,即“ item5”,“ item6”。 我有一種方法,可以遍歷整個level2對象,但想知道是否可以簡單地使用key來查找值。

您可以自己構建一個對象或(在ES2015中)構建Map

這是一個使用對象的ES5示例:

var map = Object.create(null);
data.level1.level2.forEach(function(entry) {
    Object.keys(entry).forEach(function(key) {
        map[key] = entry;
    });
});

現場示例:

 var data = { "level1": { "level2": [{ "product1": [ "item1", "item2" ] }, { "product2": [ "item1", "item2" ] }, { "product3": [ "item5", "item6" ] }] } }; var map = Object.create(null); data.level1.level2.forEach(function(entry) { Object.keys(entry).forEach(function(key) { map[key] = entry; }); }); var name = "product2"; console.log(map[name]); 

我們使用Object.create(null)創建對象( map ),以便它沒有原型,因此也沒有像toStringvalueOf這樣的預先存在的繼承屬性。

必須使用Object.keys結果上的內部循環,因為level2數組中的每個對象為其唯一屬性都具有不同的名稱。 這是一個不尋常且有點尷尬的結構。

在帶有Map ES2015(又稱“ ES6”)中,非常相似,只是使用new Mapset

var map = new Map();
data.level1.level2.forEach(function(entry) {
    Object.keys(entry).forEach(function(key) {
        map.set(key, entry);
    });
});

現場示例:

 var data = { "level1": { "level2": [{ "product1": [ "item1", "item2" ] }, { "product2": [ "item1", "item2" ] }, { "product3": [ "item5", "item6" ] }] } }; var map = new Map(); data.level1.level2.forEach(function(entry) { Object.keys(entry).forEach(function(key) { map.set(key, entry); }); }); var name = "product2"; console.log(map.get(name)); 

使用Array.someArray.indexOfObject.keys函數的“單行”優化解決方案(無需遍歷所有“產品”對象):

// json is your initial object
var key = 'product3', values;
json['level1']['level2'].some((v) => Object.keys(v).indexOf(key) !== -1 && (values = v[key]), values);

console.log(values);  // ["item5", "item6"]

說明
arr.some(callback[, thisArg]) -如果回調函數返回任何數組元素的真實值,則此函數返回true;否則,此函數返回true 在我的示例中, values變成thisArg參數,其中應包含所需的“ keyName”的值。
它將迭代所有“產品”對象,但是如果在當前對象的屬性( Object.keys(v).indexOf(key) !== -1 )中找到所需的keyName ,它將立即立即停止循環。
作為並發條件,它應保存找到的對象的值,這可以通過真實的賦值表達式&& (values = v[key])
就這樣。

您可以將數據轉換為不同的結構。

 const data = { "level1": { "level2": [{ "product1": [ "item1", "item2" ] }, { "product2": [ "item3", "item4" ] }, { "product3": [ "item5", "item6" ] }] }, "level1b": { "level2": [{ "product1": [ "item1b", "item2" ] }, { "product2": [ "item3", "item4" ] }, { "product3": [ "item5", "item6" ] }] } }; const transformed = Object .keys(data) .reduce((obj, key) => { const value = data[key]; return Object.assign(obj, {[key]: transformLvl2(value)}); }, {}); console.log(transformed.level1.level2.product2); console.log(transformed.level1.level2.product1); console.log(transformed.level1.level2.product3); console.log(transformed.level1b.level2.product1); function transformLvl2(level2) { return Object .keys(level2) .reduce((obj, key) => { const value = level2[key]; return Object.assign(obj, {[key]: transformLvl3(value)}); }, {}); } function transformLvl3(level3) { return level3 .reduce((obj, value) => { return Object.assign(obj, value); }, {}); } 

試試(假設level1level2是通用的)

 var obj = { "level1": { "level2": [{ "product1": [ "item1", "item2" ] }, { "product2": [ "item1", "item2" ] }, { "product3": [ "item5", "item6" ] }] } }; var keyName = "product3"; var items = []; Object.keys(obj).forEach(function(key) { Object.keys( obj[key] ).forEach(function(key1){ obj[key][key1].forEach(function(obj1){ Object.keys(obj1).forEach(function(key2) { if (key2 == keyName) { items = items.concat(obj1[key2]); } }); }); }); }); console.log(items); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM