簡體   English   中英

動態遍歷未知深度鍵的對象

[英]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.

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