[英]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
),以便它沒有原型,因此也沒有像toString
和valueOf
這樣的預先存在的繼承屬性。
必須使用Object.keys
結果上的內部循環,因為level2
數組中的每個對象為其唯一屬性都具有不同的名稱。 這是一個不尋常且有點尷尬的結構。
在帶有Map
ES2015(又稱“ ES6”)中,非常相似,只是使用new Map
並set
:
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.some
, Array.indexOf
和Object.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); }, {}); }
試試(假設level1
和level2
是通用的)
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.