【问题标题】:Recursively accessing key/value pairs of object within objects & combining them together into a flat array递归访问对象中对象的键/值对并将它们组合成一个平面数组
【发布时间】:2020-04-04 02:16:42
【问题描述】:

我有一个包含我所有路线的对象数组。我需要访问所有对象的嵌套子属性及其属性并将它们组合在一起。

我的对象数组如下所示:

const routes = [
  {
    path: '/system-settings1',
    name: 'global-settings1',
    component: 'tabs1',
    children: [
      {
        path: 'level2-accounting1',
        name: 'local-settings1',
        components: 'modals1',
        children: [
          {
            path: 'level3-accounting1',
            name: 'local-settings1',
            components: 'modals1'
          }
          // more children deeply nested(or not)
        ]
      },
      {
        path: 'level2-accounting1',
        name: 'local-settings1',
        components: 'modals1',
        children: [
          {
            path: 'level3-accounting1',
            name: 'local-settings1',
            components: 'modals1'
          }
          // more children deeply nested(or not)
        ]
      }
    ],
  },
  {
    path: '/system-settings2',
    name: 'global-settings2',
    component: 'tabs2',
    children: [
      {
        path: 'level2-accounting2',
        name: 'local-settings2',
        components: 'modals2',
        children: [
          {
            path: 'level3-accounting2',
            name: 'local-settings2',
            components: 'modals2'
          }
          // more children deeply nested(or not)
        ]
      },
      {
        path: 'level3-accounting2',
        name: 'local-settings2',
        components: 'modals2',
        children: [
          {
            path: 'level4-accounting2',
            name: 'local-settings2',
            components: 'modals2'
          }
          // more children deeply nested(or not)
        ],
      }
    ],
  },
  // more objects with similar key/value pairs
];

我需要将对象数组变成单级数组,如下所示:

[
  {
    path: '/system-settings1',
    name: 'global-settings1',
    component: 'tabs1',
  },
  {
    path: 'level2-accounting2',
    name: 'local-settings2',
    components: 'modals2',
  },
  {
    path: 'level3-accounting1',
    name: 'local-settings1',
    components: 'modals1'
  },
  {
    path: 'level2-accounting1',
    name: 'local-settings1',
    components: 'modals1',
  }
  // so on if there is more objects etc
]

我曾尝试将.map().filter()while 循环结合使用,但老实说,我缺乏自己完成的技能并且不值得包括我的尝试。如果有人可以帮助我并解释,将不胜感激。

【问题讨论】:

  • 在 javascript(和大多数其他语言)中,对象键必须是唯一的,因此您不能在单个对象上拥有多个“路径”、“名称”或“组件”属性。你想用扁平物体做什么?编辑 - 我想我现在明白了这个问题,我认为想要的结果只是令人困惑。
  • 对不起,我知道这很混乱。我需要将具有属性路径、名称、父组件及其子组件(及其子组件等)的新对象数组制作成一个扁平的对象数组,稍后我将在表格上可视化。
  • 你希望每条路由在数组中都有一个条目,不管它是否是孩子,对吗?
  • 是的,没错。它基本上是抓住孩子及其孩子的所有属性并带回第一级。

标签: javascript arrays object recursion nested-routes


【解决方案1】:

我尝试编辑您的代码示例,使它们有意义并且运行时没有错误。这是在根 routes 数组以及任何嵌套的 children 数组上调用的递归函数:

const flatten = routes => {
  const flattened = [];

  for (let i = 0; i < routes.length; i++) {
    const route = routes[i];

    //for each route, grab only the information about the route itself (no children)
    const { path, name, components } = route;
    const flatRoute = { path, name, components };

    //add the new route object to our return array
    flattened.push(flatRoute);

    //if the route had children, recursively call flatten on them
    //and add each child to our return array
    if (route.children) {
      const flatChildren = flatten(route.children);
      flattened.push(...flatChildren);
    }
  }

  return flattened;
};

【讨论】:

  • 首先,感谢您的帮助。我试过jsfiddle.net/ga8r31dh,但我没有让它工作
  • 我认为您原始帖子中的代码无效,因为routes 数组中的对象具有多个子属性。请参阅 this fiddle 以获取清理 routes 对象的示例
【解决方案2】:

这是一个非常简单的 ES6 函数。它可能不是可用的性能最高的版本,但它很简单。

const flattenAll = (xs) => xs .reduce (
  (all, {children, ...rest}) => [...all, {...rest}, ...flattenAll(children || [])],
  []
)

const routes = [{path: "/system-settings1", name: "global-settings1", component: "tabs1", children: [{path: "level2-accounting1", name: "local-settings1", components: "modals1", children: [{path: "level3-accounting1", name: "local-settings1", components: "modals1"}]}, {path: "level2-accounting1", name: "local-settings1", components: "modals1", children: [{path: "level3-accounting1", name: "local-settings1", components: "modals1"}]}]}, {path: "/system-settings2", name: "global-settings2", component: "tabs2", children: [{path: "level2-accounting2", name: "local-settings2", components: "modals2", children: [{path: "level3-accounting2", name: "local-settings2", components: "modals2"}]}, {path: "level3-accounting2", name: "local-settings2", components: "modals2", children: [{path: "level4-accounting2", name: "local-settings2", components: "modals2"}]}]}];

console .log (flattenAll (routes))

请注意,这使用深度优先排序;我猜广度优先的代码会更丑陋,但我还没有尝试过。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多