簡體   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