【问题标题】:Recursive function to flatten nested array and keeping track of all parent nodes (Javascript)用于展平嵌套数组并跟踪所有父节点的递归函数(Javascript)
【发布时间】:2020-11-07 12:56:47
【问题描述】:

嗨,我有一个函数,它采用嵌套的包含孩子的父母数组并将其展平。但是,我还想跟踪其所有更高节点的 ID。

示例数据结构:

[{
    id: 1,
    type: "group",
    name: "Colors",
    items: [
      { id: 2, type: "item", name: "Red", items: [] },
      { id: 3, type: "item", name: "Purple2", items: [] },
      {
        id: 4,
        type: "item",
        name: "Black",
        items: [
          {
            id: 5,
            type: "item",
            name: "Purple3",
            items: [],
          },
          { id: 6, type: "item", name: "Purple4", items: [] },
        ],
      },
    ],
  }]

这是当前的最终结果(这正是我想要实现的),但下面的潜在功能可以重构。

{id: 1, name: "Colors", depth: 1, parentId: null, main: []}
1: {id: 2, name: "Red", depth: 2, parentId: 1, main: [1]}
2: {id: 3, name: "Purple2", depth: 2, parentId: 1, main: [1]}
3: {id: 4, name: "Black", depth: 2, parentId: 1, main: [1]}
4: {id: 5, name: "Purple3", depth: 3, parentId: 4, main: [1,4]} // main stores id of all higher parents e.g. id 4 = "black" and parent of 4 = "Colors"
5: {id: 6, name: "Purple4", depth: 3, parentId: 4, main: [1,4]}

我目前的扁平化数组函数:

const flattenArr = (data, depth = 1, parent = null) => {
  const result = [];

  data.forEach((item) => {
    const { id, name, items } = item;
    result.push({
      id,
      name,
      depth,
      parentId: parent,
      main: [],
    });

    if (items) result.push(...flattenArr(items, depth + 1, item.id));
  });

  return result;
};

以下函数用于跟踪所有父 ID。但是,它似乎不是我可以使用的最佳解决方案,因此我想知道是否可以改进它,以便在一个递归函数中全部完成。

const collectParents = (arr) => {
  for (let b = 0; b < arr.length; b++) {
    if (arr[b].depth !== 1) {
      arr[b].main.push(
        ...arr[b - 1].main,
        arr[b - 1].depth === arr[b].depth - 1 ? arr[b - 1].id : null
      );
    }
  }

  arr.forEach((x) => (x.main = x.main.filter((i) => i !== null)));
};

【问题讨论】:

    标签: javascript algorithm recursion


    【解决方案1】:

    您可以使用 reduce 方法创建递归函数并传递父 ID 和以前的 ID 数组。

    const data = [{"id":1,"type":"group","name":"Colors","items":[{"id":2,"type":"item","name":"Red","items":[],"top":{}},{"id":3,"type":"item","name":"Purple2","items":[]},{"id":4,"type":"item","name":"Black","items":[{"id":5,"type":"item","name":"Purple3","items":[]},{"id":6,"type":"item","name":"Purple4","items":[]}]}]}]
    
    function flatten(data, depth = 0, parentId = null, main = []) {
      return data.reduce((r, { items, id, ...rest }) => {
        const obj = { ...rest, id, depth, parentId, main }
        r.push(obj)
        
        if (items.length) {
          r.push(...flatten(items, depth + 1, id, [...main, id]))
        }
        
        return r;
      }, [])
    }
    
    const result = flatten(data)
    console.log(result)

    【讨论】:

      【解决方案2】:

      你不能在 maindepth 上关闭 Array#flatMap

      const
          flat = (main = [], depth = 1,) => ({ top, type, items = [], ...o }) => [
              { ...o, depth, parentId: main[0] ?? null, main },
              ...items.flatMap(flat([...main, o.id], depth + 1))
          ],
          tree = [{ id: 1, type: "group", name: "Colors", items: [{ id: 2, type: "item", name: "Red", items: [], top: new Set() }, { id: 3, type: "item", name: "Purple2", items: [] }, { id: 4, type: "item", name: "Black", items: [{ id: 5, type: "item", name: "Purple3", items: [] }, { id: 6, type: "item", name: "Purple4", items: [] }] }] }],
          result = tree.flatMap(flat());
      
         console.log(result);
      .as-console-wrapper { max-height: 100% !important; top: 0; }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-15
        • 2015-02-02
        • 2021-02-24
        • 1970-01-01
        • 2015-07-14
        • 2019-07-04
        • 2018-11-13
        • 2021-09-08
        相关资源
        最近更新 更多