第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何理解在javascript反應中將數(shù)組轉(zhuǎn)換為樹數(shù)組的函數(shù)代碼片段?

如何理解在javascript反應中將數(shù)組轉(zhuǎn)換為樹數(shù)組的函數(shù)代碼片段?

婷婷同學_ 2022-09-16 21:15:54
我有將簡單的對象數(shù)組轉(zhuǎn)換為樹數(shù)組的函數(shù)。該函數(shù)不是我編寫的。該函數(shù)使用洛達什 _.each。它與本機相同下面是代碼和示例數(shù)據(jù):let a = [    {        id: 1,        name: "ADMINISTRATION"    },    {        id: 2,        name: "ADMIN_GROUP",        parentId: 1    },    {        id: 3,        name: "ADMIN_GROUP_CREATE",        parentId: 2    },    {        id:168,        name: "HELP_EDIT"    }]function makeTreeFromArray(list) {  const treeArray = [];  const treeMap = {};  _.each(list, (item, index) => {    treeMap[item.id] = index;    // list[index].children = [];    item.children = [];  });  _.each(list, item => {    if (item.parentId) {      list[treeMap[item.parentId]].children.push(item);    } else {      treeArray.push(item);    }  });  console.log('treeMap', treeMap);  console.log('list', list);  return treeArray;}const newArr = makeTreeFromArray(a);console.log(newArr);這是輸出:我不明白這段代碼:..._.each(list, item => {    if (item.parentId) {      list[treeMap[item.parentId]].children.push(item);    } else {      treeArray.push(item);    }...我得到了一個由兩個對象組成的樹數(shù)組,但為什么有兩個對象?我真的很累,很困惑。在這里,最初樹陣列是空的。然后,僅當項目沒有“父 Id”時,才會推送該項目。如果它有“父 Id” - 則應用適當?shù)倪壿嫛2⑶颐總€子項被推送到相應的父項的“子項”屬性。原始列表發(fā)生了變異。但是沒有樹的“氣味”。復雜的父對象位于列表數(shù)組中。我說的對嗎?但是為什么在最后,樹陣列由兩個對象組成,而不是一個對象?為什么復雜的父對象會神奇地出現(xiàn)在樹數(shù)組中?
查看完整描述

2 回答

?
慕沐林林

TA貢獻2016條經(jīng)驗 獲得超9個贊

這是一種生成樹的非常簡單的方法,但理想情況下,您需要了解JavaScript中的指針/引用才能了解它是如何工作的。(它確實創(chuàng)建了很多指針/引用,還有其他方法可以用更少的指針和更少的內(nèi)存使用量來做到這一點。此外,這僅在對平面列表進行排序并且確實會改變原始列表時才有效。還有其他方法可以從平面數(shù)組生成樹,使用遞歸等,并且不會改變列表)


重要的是,基元(數(shù)字、布爾值等)存儲在堆棧上,對象(如數(shù)組、對象等)存儲在堆上。對象的變量只是指向堆上對象位置的指針。我不確定推薦什么文章或YouTube視頻,因為我閱讀/觀看了這么多不同的文章或視頻 - https://www.google.com/search?q=stack+vs+heap


堅持你的例子,讓我試著逐行解釋(在代碼中加上注釋):


let a = [

    {   id: 1,    name: "ADMINISTRATION"    },

    {   id: 2,    name: "ADMIN_GROUP",        parentId: 1    },

    {   id: 3,    name: "ADMIN_GROUP_CREATE", parentId: 2    },

    {   id:168,   name: "HELP_EDIT"         }

]


function makeTreeFromArray(list) {

  const treeArray = [];

  const treeMap = {};

  

  //this loop generates the treeMap

  //and adds a .children prop to each item in the list:

  list.forEach((item, index) => {

    treeMap[item.id] = index;

    // list[index].children = [];

    item.children = [];

  });

  //Output of that function:

  //it maps ids to index in the list

  /*

  treeMap = {

    "1": 0,

    "2": 1,

    "3": 2,

    "168": 3

  }

  */

  

  //this loop pushes each child to its parent in the original list (if it has a parentId)

  //and it does this using the treeMap (essentially a lookup of ids to indexes).

  //if the child does not have a parent, then it is the highest level parent

  //in this case, push it to our output treeArray (with all its children):

  list.forEach(item => {

    if (item.parentId) {

      list[treeMap[item.parentId]].children.push(item);

    } else {

      treeArray.push(item);

    }

  });


  //console.log('treeMap', treeMap);

  //console.log('list', list);

  return treeArray;

}


const newArr = makeTreeFromArray(a);

console.log(newArr);

它之所以有效,是因為如果創(chuàng)建指針/引用(原始指針的副本),則可以通過原始指針或新副本更新原始項目。下面是一個微不足道的例子:


了解如何使用任一變量更改原始數(shù)據(jù)(同樣重要的是,我們正在使用對象,使用基元,這將是不一樣的)。


(注意:JavaScript 是垃圾回收的,因此每當堆上指向內(nèi)存的所有指針都超出范圍時,就會清理數(shù)據(jù)。默認情況下,JavaScript使處理內(nèi)存變得“簡單”,但是隨著您更深入地了解它正在做的事情,它變得更加復雜。像C++或Rust這樣的低級語言讓你自己管理內(nèi)存 - 但Rust通過編譯器幫助你做到這一點,C++你基本上是獨立的,可能會導致問題)


//original is a pointer to a location on the heap, where the object lives:

const original = {id: 1, children: []};


//pointerToOriginal is just a copy of the original pointer,

//so now they both point to the same location on the heap:

const pointerToOriginal = original;


//I can use either pointer, to change the object on the heap:

pointerToOriginal.id +=1;


//and it can be seen with both pointers (as they point to the same object):

console.log(pointerToOriginal, original);


//I can use either pointer, to change the object on the heap:

original.id +=1;


//and it can be seen with both pointers (as they point to the same object):

console.log(pointerToOriginal, original);


//Finally, we can see that the objects are equal

//and by default JavaScript just compares the memory addresses of each pointer:

console.log(pointerToOriginal == original); //true

如果你想制作真正的副本,你需要這樣做。對于只有基元數(shù)據(jù)的“平面”對象,您可以像這樣執(zhí)行此操作(使用散布運算符)。對于嵌套對象和/或以 Object 作為其值的對象,這不會完全開箱即用,因為它只會創(chuàng)建一個“淺層副本”,但我們可以創(chuàng)建一個深度復制函數(shù)(但這是一個很長的討論):


//original is a pointer to a location on the heap, where the object lives:

const original = {id: 1, children: []};


//pointerToOriginal is now a new pointer to a shallow copy of the original object,

//so now they both point to DIFFERENT locations on the heap:

const pointerToNewCopy = {...original};


//Each pointer now only updates its Object on the heap:

pointerToNewCopy.id +=1;


//we see the orignal is un-changed:

console.log(pointerToNewCopy, original);


//Each pointer now only updates its Object on the heap:

original.id +=1;


//we see the pointerToNewCopy is un-changed:

console.log(pointerToNewCopy, original);


//Finally, we can see that the objects are not equal (even though all props are the same)

//this is because by default JavaScript just compares the memory addresses of each pointer:

console.log(pointerToNewCopy == original); //false

重要的是,我們使用上面的對象,使用基元,它將是不一樣的:


//primitive example:


let original = 5;

let copy = original;


//only the copy changes:

copy +=1;

console.log(copy, original);


//only the original changes:

original +=1;

console.log(copy, original);

如果您從函數(shù)中 return 語句之前的最后一行(或者您可以在函數(shù)運行后向外調(diào)用它,因為它改變了原始列表),您將看到以下內(nèi)容(在此代碼段的控制臺中,Google chrome 控制臺不會通知您有指針/引用副本)。需要注意的重要事項是,id=1 的子級是該列表中原始項(ref4 和 ref6)的引用副本:console.log(list)makeTreeFromArray(list)


這就是樹的構建方式,從這個突變的原始列表中。希望現(xiàn)在有意義嗎?這是一個不平凡的話題。


list = [

  {

    "id": 1,

    "name": "ADMINISTRATION",

    "children": [

      {

        /**id:4**/

        "id": 2,

        "name": "ADMIN_GROUP",

        "parentId": 1,

        "children": [

          {

            /**id:6**/

            "id": 3,

            "name": "ADMIN_GROUP_CREATE",

            "parentId": 2,

            "children": []

          }

        ]

      }

    ]

  },

  /**ref:4**/,

  /**ref:6**/,

  {

    "id": 168,

    "name": "HELP_EDIT",

    "children": []

  }

]


查看完整回答
反對 回復 2022-09-16
?
臨摹微笑

TA貢獻1982條經(jīng)驗 獲得超2個贊

我得到了一個由兩個對象組成的樹數(shù)組,但為什么有兩個對象?

您正確地標識了沒有 的對象將追加到該數(shù)組中。輸入數(shù)組中有兩個這樣的對象。由于它們沒有對父級的引用,因此應將其視為頂級對象,這就是為什么您應該在 中看到兩個對象的原因。所有其他輸入對象都應該在某個屬性的更深處找到。parentIdtreeArraychildren

如果它有“父 Id” - 則應用適當?shù)倪壿?。并且每個子項被推送到相應的父項的“子項”屬性。原始列表發(fā)生了變異。但是沒有樹的“氣味”。

實際上, 在代碼的該部分中未被引用。但是我們遲早會有一個對象A,它的父對象(B)將是一個頂級對象,即沒有父對象。treeArray

我們知道,當訪問 B 時(可能在 A 之前或 A 之后,這并不重要),它將被添加到 。因此,盡管沒有直接引用,但通過將A添加到B的屬性中,我們會影響(或?qū)⒁┩扑偷膬?nèi)容。treeArraytreeArraychildrentreeArray

換句話說:通過突變B的屬性(當我們向它添加A時),我們也(間接地)突變(如果B已經(jīng)在其中),或者將突變的B推入(如果B仍然被添加到其中)。childrentreeArraytreeArray

因此,通過將對象添加到其他對象的數(shù)組中,我們創(chuàng)建了一個嵌套對象的集合體。只有沒有父級的對象才能保持“獨立”:它們最終在 中,但與它們一起“拖動”一個包含所有嵌套對象的子樹,這些子對象可能有自己的對象,...等。childrentreeArraychildrenchildren


查看完整回答
反對 回復 2022-09-16
  • 2 回答
  • 0 關注
  • 123 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號