首页 > 解决方案 > 如何在多级对象和许多分支中将子数组连接到父数组?

问题描述

给定一个具有任意深度嵌套数组的对象,我如何提取子数组的不同值并将它们转换为一个值。

例如:

const bigObj = {
    parent1: {
        subParent1: {
            user1: [1, 2, 3],
            user2: [3, 4, 5]
        },
        subParent2: {
            user3: [6, 7, 8],
            user4: [7, 8, 9]
        }
    },
    parent2: {
        subParent3: {
            user5: [a, b, c],
            user6: [d, e, f]
        },
        subParent4: {
            subSubParent1: {
                user7: [g, h, i],
                user8: [j, k, l]
            }
            user9: [m, n, o],
        }
    }
}

我想把它变成这样的东西:

const bigObj = {
    parent1: {
        subParent1: {
            user1: [1, 2, 3],
            user2: [3, 4, 5],
            values: [1, 2, 3, 4, 5]
        },
        subParent2: {
            user3: [6, 7, 8],
            user4: [7, 8, 9],
            values: [6, 7, 8, 9]
        },
        values: [1, 2, 3, 4, 5, 6, 7, 8, 9]
    },
    parent2: {
        subParent3: {
            user5: [a, b, c],
            user6: [d, e, f],
            values: [a, b, c, d, e, f]
        },
        subParent4: {
            subSubParent1: {
                user7: [g, h, i],
                user8: [j, k, l],
                values: [g, h, i, j, k, l]
            }
            user9: [m, n, o],
            values: [g, h, i, j, k, l, m, n, o]
        },
        values: [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o]
    },
    values: [1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o]
}

如何使用 vanilla Javascript 实现这一目标?我不想使用库或框架,只是普通的 JS。这只是一个例子,对象可以有许多层次和许多数组。

非常感谢。

标签: javascriptarraysobjectmultidimensional-array

解决方案


您需要一个将值映射到更高级别的递归函数。

const bigObj = {
  parent1: {
    subParent1: {
      user1: [1, 2, 3],
      user2: [3, 4, 5]
    },
    subParent2: {
      user3: [6, 7, 8],
      user4: [7, 8, 9]
    }
  },
  parent2: {
    subParent3: {
      user5: ["a", "b", "c"],
      user6: ["d", "e", "f"]
    },
    subParent4: {
      subSubParent1: {
        user7: ["g", "h", "i"],
        user8: ["j", "k", "l"]
      },
      user9: ["m", "n", "o"],
    },
  },
}

const mapValues = (obj) => {
  let ret = []
  for (key in obj) {
    // this is the recursion stopping condition: if the obj[key]
    // is an array, then recursion stops, the function doesn't
    // call itself
    if (Array.isArray(obj[key])) {
      // [...new Set(/*...*/)] is to ensure that only unique values
      // are in your values - according to your example
      ret = [...new Set([...ret, ...obj[key]])]
    } else {
      // here's the recursion: the function calls itself -
      // now with a different object as argument: obj[key]
      ret = [...new Set([...ret, ...mapValues(obj[key])])]
    }
  }
  obj["values"] = ret
  return ret
}

const fullList = mapValues(bigObj)

console.log("modified object:", bigObj)


推荐阅读