[英]Dynamically traverse an object of unknown depth's keys
我有一個奇怪的問題——可能是一個愚蠢的問題——需要一些解釋,所以請耐心等待。 基本上,我想知道是否有一種方法可以在不使用遞歸的情況下遍歷 JavaScript 中未知深度的對象。
例如,假設我有一個未知深度的對象。 它看起來像這樣:
let obj_depth2 = {
male:
{ short: 0, tall: 0 },
female:
{ short: 0, tall: 0 }
}
或者像這樣:
let obj_depth3 = {
male: {
short:
{ basketball: 0, soccer: 0 },
tall:
{ basketball: 0, soccer: 0 }
},
female: {
short:
{ basketball: 0, soccer: 0 },
tall:
{ basketball: 0, soccer: 0 }
}
}
obj
也可能更深。 我不會提前知道它的深度。
讓我們進一步假設我將有一個看起來像這樣的arr
,並且長度與obj
的深度相匹配。
let arr_depth2 = ["male", "short"];
或者
let arr_depth3 = ["male", "tall", "basketball"];
我將有一個循環,在其中生成 1,000 個這些arr
,然后我將使用這些循環將1
添加到未知深度的obj
中。 所有arr
的長度都相同(2 或 3,或更多)並且將始終匹配obj
的深度。 但是深度會發生變化,我想編寫一個函數來涵蓋所有情況。
需要明確的是,我不會遇到深度為 2 的obj
和長度為 3 的arr
的情況。深度和長度將始終匹配所有 1,000 次迭代。
我的問題是這個。 有沒有辦法遍歷obj
以在不使用遞歸的情況下將我需要達到的“最深”鍵值對的值加1
?
我可以建造這樣的東西嗎?
obj["male"]["short"] += 1;
雖然我知道我可以使用遞歸來達到深度底部obj
,加1
到適當value
,並return
它,重建obj
的遞歸函數繼續return
,這意味着我將不得不重建obj
每單value 並覆蓋我剛剛在上一次迭代中構建的obj
,只是將1
添加到obj
一部分。 這看起來很糟糕,但也許沒關系。
先感謝您。
您可以使用.reduce()
來遍歷您的對象,累加器在您的遍歷中跟蹤您當前的對象。 當您的reduce 完成時,它將在您的路徑中包含最內部的嵌套對象,然后您可以使用數組中的最后一個元素作為鍵來修改值。 正如您所說,如果您對簡單地改變原始對象感到滿意,則不需要遞歸:
const obj = {male:{short:{basketball:0,soccer:0},tall:{basketball:0,soccer:0}},female:{short:{basketball:0,soccer:0},tall:{basketball:0,soccer:0}}} const arr = ["male", "tall", "basketball"]; const modify = (obj, [...keys]) => { const last_key = keys.pop(); const last_obj = keys.reduce((o, k) => o[k], obj); last_obj[last_key] += 1; } modify(obj, arr); console.log(obj);
如果您嘗試就地修改對象,您基本上可以使用指針遍歷對象到到達最后一個鍵的點,然后設置它。
const obj_depth3 = { male: { short: { basketball: 0, soccer: 0 }, tall: { basketball: 0, soccer: 0 } }, female: { short: { basketball: 0, soccer: 0 }, tall: { basketball: 0, soccer: 0 } } } const addOneTo = (obj, path) => { const finalProp = path.pop(); const pointer = path.reduce((pointer, key) => pointer[key], obj); pointer[finalProp]++; } addOneTo(obj_depth3, ["male", "short", "soccer"]) console.log(obj_depth3);
您可以使用 reduce 函數在您描述的情況下安全地訪問嵌套對象:
const getNestedObject = (nestedObj, pathArr) => {
return pathArr.reduce((obj, key) =>
(obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);
}
然后你可以以類似的方式訪問你想要的 ['male']['short'] 對象:
let shortMale = getNestedObject(obj_depth3, ['male', 'short'])
您可以對對象執行所需的操作:
shortMale.basketball += 1
有關 getNestedObject 函數的更多信息,請參見: https ://hackernoon.com/accessing-nested-objects-in-javascript-f02f1bd6387f
這是一個公式,一旦您可以在 JavaScript 中調用文件夾名稱,就可以獲取未知大小事物的所有部分Object.entries(yourObject)
這將返回一個包含對象所有數據的數組,以便您可以輕松地遍歷它。 我會在示例中返回您的數據,以向您展示 Object.entries 的工作原理
const obj_depth3 = { male: { short: { basketball: 0, soccer: 0 }, tall: { basketball: 0, soccer: 0 } }, female: { short: { basketball: 0, soccer: 0 }, tall: { basketball: 0, soccer: 0 } } } console.log(Object.entries(obj_depth3)); //you might still want to use another console like inspect element's own to see how the array works, but it has all the depth and stuff :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.