繁体   English   中英

Javascript递归树构建

[英]Javascript Recursion Tree Building

我在从平面数组构建树时遇到问题。 我正在构建一个类别-> 子类别树,其中父级将子类别作为数组。

这是平面数组的样子:

[
  {
    "id": 1
  },
  {
    "id": 5,
  },
  {
    "id": 2,
    "parent_id": 1
  },
  {
    "id": 3,
    "parent_id": 1
  },
  {
    "id": 42,
    "parent_id": 5
  },
  {
    "id": 67,
    "parent_id": 5
  }
]

这就是我需要查看的结果:

[
  {
    "id":1,
    "subcategories":[
      {
        "id":2,
        "parent_id":1
      },
      {
        "id":3,
        "parent_id":1
      }
    ]
  },
  {
    "id":5,
    "subcategories":[
      {
        "id":42,
        "parent_id":5
      },
      {
        "id":67,
        "parent_id":5
      }
    ]
  }
]

我试图通过递归搜索孩子并将其作为数组附加并继续这样做,直到我到达桶底,但我得到了一个循环结构。 看来 traverse 中的 parent_id 始终是父级的 id ...任何想法:

tree(passingInFlatObjectHere);

function topLevel (data) {
  let blob = [];
  data.forEach((each) => {
    if (!each.parent_id) {
      blob.push(each);
    }
  });
  return blob;
}

function tree (data) {
  let blob = topLevel(data).map(function (each) {
    each.subcategories = traverse(data, each.id);
    return each;
  });
  return blob;
}

function traverse (data, parent_id) {
  let blob = [];
  if (!parent_id) {
    return blob;
  }
  data.forEach((each) => {
    if (each.id === parent_id) {
      each.subcategories = traverse(data, each.id);
      blob.push(each);
    }
  });
  return blob;
}

我不仅想帮你解决问题,还想帮助你充分利用 ES6

首先,您的topLevel函数可以重写为:

function topLevel(data) {
  return data.filter(node => !node.parent_id);
}

整齐是不是? 我还建议稍微改变tree以保持一致性,但这当然只是风格。

function tree(data) {
  return topLevel(data).map(each => {
    each.subcategories = traverse(data, each.id);
    return each;
  });
}

目前没有逻辑问题。 但是,当您检查each.id === parent_id时, traverse包含一个。 像这样,函数搜索 id 为parent_id的节点。 显然是一个错误。 你想要each.parent_id === parent_id

你的问题现在已经解决了。 如果我打扰你,请停止阅读。 但是您也可以利用此处的filter并删除稍微多余的提前退出并将您的函数重写为:

function traverse(data, parentId) {
  const children = data.filter(each => each.parent_id === parentId);
  children.forEach(child => {
    child.subcategories = traverse(data, child.id);
  });
  return children;
}

首先,您需要使用 npm 使用以下命令安装lodash

npm i lodash

其次,必须从 lodash 导入 _

import _ from "lodash";

最后,运行这个函数:

export const recursive_lists = (data) => {
  const grouped = _.groupBy(data, (item) => item. parent_id);

  function childrenOf(parent_id) {
    return (grouped[parent_id] || []).map((item) => ({
      id: item.id,
      child: childrenOf(item.id),
    }));
  }

  return childrenOf(null);
};

或者

第一的:

<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.20/lodash.min.js"></script>

第二:

function recursive_lists(data) {
  const grouped = _.groupBy(data, (item) => item.parent_id);

  function childrenOf(parent_id) {
    return (grouped[parent_id] || []).map((item) => ({
      id: item.id,
      child: childrenOf(item.id),
    }));
  }

  return childrenOf(null);
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM