ist/Arrray數(shù)據(jù)轉(zhuǎn)樹形數(shù)據(jù)

list/Arrray數(shù)據(jù)轉(zhuǎn)樹形數(shù)據(jù)

const treeData = [
      { id: '1000', pid: null, name: '西安總部' }, // 1級
      { id: '10001', pid: '1000', name: '西安雁塔分部 - 子公司' }, // 2級
      { id: '10002', pid: '1000', name: '西安蓮湖分部 - 子公司' }, // 2級
      { id: '100021', pid: '2000', name: '西安蓮湖分部 - 西桃園分部 - 子公司' }, // 3級
      { id: '2000', pid: null, name: '北京總部' }, // 1級
      { id: '20001', pid: '2000', name: '北京豐臺分部 - 子公司' }, // 2級
      { id: '20002', pid: '2000', name: '北京朝陽分部 - 子公司' }, // 2級
      { id: '200021', pid: '1000', name: '北京朝陽分部 - 廣渠路分部 - 子公司' } // 3級
    ]

    // 方法1
    const listToTree1 = (list = [], option = {}) => {
      option.selfKey = option.selfKey ? option.selfKey : 'id'
      option.parentKey = option.parentKey ? option.parentKey : 'pid'
      option.childrenKey = option.childrenKey ? option.childrenKey : 'children'

      const tree = []

      const idMapping = list.reduce((acc, item, index) => {
        acc[item[option.selfKey]] = index
        return acc
      }, {})

      for (const item of list) {
        if (!item[option.parentKey]) {
          tree.push(item)
          continue
        }

        const parent = list[idMapping[item[option.parentKey]]]
        parent.children = [...(parent.children || []), item]
      }
      return tree
    }

    console.log(listToTree1(treeData))

    // 方法2: 遞歸遍歷children
    const listToTree2 = (list = [], pid) => {
      const result = list.filter(item => {
        if (item.pid === pid) {
          item.children = listToTree2(list, item.id)
          return true
        }
        return false
      })
      return result
    }
    console.log(listToTree2(treeData, null))

    // 方法3: 查詢每個節(jié)點的parent脖母,查到parent之后究流,內(nèi)部循環(huán)就可以截止了篓像。(使用find方法)
    const listToTree3 = (list = [], pid) => {
      const result = list.filter(item => {
        if (item.pid !== pid) {
          let parent = list.find(parent => parent.id = item.pid)
          if(!parent.children) parent.children = []
          parent.children.push(item)
          return false
        }
        return true
      })
      return result
    }
    console.log(listToTree3(treeData, null))

    // 方法4:在方法3的基礎上夺英,將每次find的parentNode緩存起來,減少相同parent的查詢次數(shù) 
    const listToTree4 = (list, parentId) => {
      let parentObj = {}
      return list.filter(item => {
        if (item.pid !== parentId) {
          if (!parentObj[item.pid]) {
            parentObj[item.pid] = list.find(parent => parent.id === item.pid)
            parentObj[item.pid].children = []
          }
          parentObj[item.pid].children.push(item)
          return false
        }
        return true
      })
    }
    console.log(listToTree4(treeData, null))

    // 方法5: 遍歷tree之前狐赡,先遍歷一遍數(shù)組撞鹉,將數(shù)據(jù)緩存到object中。二次遍歷,直接使用object中的緩存
    const listToTree5 = (list) => {
      let mapObj = {}
      list.forEach(item => {
        item.children = []
        mapObj[item.id] = item
      })
      const result = list.filter(item => {
        if (item.pid !== null) {
          mapObj[item.pid].children.push(item)
          return false
        }
        return true
      })
      return result
    }
    console.log(listToTree5(treeData))

   // 該方法使用Map數(shù)據(jù)結構孔祸,將每個節(jié)點的id作為鍵隆敢,節(jié)點作為值存儲发皿。然后使用循環(huán)來遍歷列表崔慧,將每個節(jié)點連接到其父節(jié)點。
  function convertToTree(list) {
    const map = new Map(list.map((item) => [item.id, item]));
      const tree = [];
      for (const item of list) {
        if (item.parent === null) {
          tree.push(item);
          continue;
        }
        const parent = map.get(item.parent);
        if (parent) {
          parent.children = parent.children || [];
          parent.children.push(item);
        }
      }
      return tree;
    }
   convertToTree(treeData)

     const data = [
        { id: 1, parentId: null, name: 'A' },
        { id: 2, parentId: 1, name: 'B' },
        { id: 3, parentId: 1, name: 'C' },
        { id: 4, parentId: 3, name: 'D' },
        { id: 5, parentId: 4, name: 'E' }
      ];

      // 此代碼通過遍歷數(shù)組并使用 reduce 方法將扁平化的對象數(shù)組轉(zhuǎn)換為樹形結構穴墅。在 reduce 方法的初始值中創(chuàng)建一個空對象惶室,
      // 然后對于數(shù)組中的每個元素,如果該元素的 parentId 屬性為空玄货,則將其添加到初始對象中皇钞;否則,將其作為子節(jié)點添加到其父節(jié)點中松捉。
      // 最后夹界,將轉(zhuǎn)換后的對象中的所有值作為數(shù)組返回。

      const tree = data.reduce((acc, item) => {
        if (!item.parentId) {
          acc[item.id] = { ...item, children: [] };
        } else {
          const parent = acc[item.parentId];
          if (parent) {
            parent.children = [...(parent.children || []), { ...item, children: [] }];
          }
        }
        return acc;
      }, {});

      const result = Object.values(tree);

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末隘世,一起剝皮案震驚了整個濱河市可柿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌丙者,老刑警劉巖复斥,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異械媒,居然都是意外死亡目锭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進店門纷捞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來痢虹,“玉大人,你說我怎么就攤上這事主儡〗蔽ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵缀辩,是天一觀的道長臭埋。 經(jīng)常有香客問我,道長臀玄,這世上最難降的妖魔是什么瓢阴? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮健无,結果婚禮上荣恐,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好叠穆,可當我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布少漆。 她就那樣靜靜地躺著,像睡著了一般硼被。 火紅的嫁衣襯著肌膚如雪示损。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天嚷硫,我揣著相機與錄音检访,去河邊找鬼。 笑死仔掸,一個胖子當著我的面吹牛脆贵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播起暮,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼卖氨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了负懦?” 一聲冷哼從身側(cè)響起筒捺,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎密似,沒想到半個月后焙矛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡残腌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年村斟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抛猫。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蟆盹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出闺金,到底是詐尸還是另有隱情逾滥,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布败匹,位于F島的核電站寨昙,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏掀亩。R本人自食惡果不足惜舔哪,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望槽棍。 院中可真熱鬧捉蚤,春花似錦抬驴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至陕悬,卻和暖如春题暖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背墩莫。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工芙委, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留逞敷,地道東北人狂秦。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像推捐,于是被迫代替她去往敵國和親裂问。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內(nèi)容