簡體   English   中英

如何干凈地循環遍歷嵌套對象?

[英]How do I cleanly loop through nested objects?

如何以干凈的方式遍歷嵌套對象? 我正在嘗試獲取此結構的 object 第三層的值:

const myObj = {
  firstObj: {
    nested: {
      anotherNest: 'i want to get this value'
    },
    again: {
      'i want this value ->': ':D'
    }
  }
}

顯而易見的解決方案是三個嵌套的 for 循環:

for (const key1 of Object.keys(myObj))
  for (const key2 of Object.keys(myObj[key1]))
    for (const key3 of Object.keys(myObj[key1][key2]))
      ...

該解決方案根本不干凈(並且無法擴展)。 我該如何解決這個問題?

您在這里所做的大部分工作是迭代 object 的第三級值。您可以創建一個迭代器來為您執行此操作。 生成器函數非常適合此用途,因為您可以輕松地遞歸使用它們。 以下代碼(在 Typescript 中)將允許您輕松地執行此操作:

type NestedObjects <T> = {
  [key: string]: NestedObjects <T> | T
}

/**
 * Iterates through all values nested at n levels deep.
 * Every iteration yields an array containing all keys looped through, in reverse.
 * This means that the first entry will be the value at n levels, followed by keys at n-1, n-2, etc.
 *
 * Example:
 * <pre>
 * for (const x of NestedObjectIterator(a, 3)) ...
 * </pre>
 *
 * is equivalent to three nested for loops:
 * <pre>
 * for (const x of Object.keys(a))
 *  for (const y of Object.keys(a[x]))
 *   for (const z of Object.keys(a[x][y])) ...
 * </pre>
 */
function * NestedObjectIterator <T> (obj: NestedObjects<T>, levels: number, ...prevKeys: string[]): Iterable<[T, ...string[]]> {
  for (const key of Object.keys(obj)) {
    if (levels === 1) yield [obj[key] as T, key, ...prevKeys]
    else if (obj[key]) yield * NestedObjectIterator(obj[key] as NestedObjects<T>, levels - 1, key, ...prevKeys)
  }
}

相當於純 Javascript:

function * NestedObjectIterator (obj, levels, ...prevKeys) {
  for (const key of Object.keys(obj)) {
    if (levels === 1) yield [obj[key], key, ...prevKeys]
    else if (obj[key]) yield * NestedObjectIterator(obj[key], levels - 1, key, ...prevKeys)
  }
}

您現在可以像這樣循環訪問 object:

const myObj = {
  firstObj: {
    nested: {
      anotherNest: 'i want to get this value'
    },
    again: {
      'i want this value ->': ':D'
    }
  }
}

for (const [value] of NestedObjectIterator(myObj, 3)) {
  console.log(value)
}

暫無
暫無

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

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