㈠ js樹結構數據的遍歷
title: JS樹結構數據的遍歷
date: 2022-04-14
description: 針對項目中出現樹形結構數據的時候,我們怎樣去操作他
項目中我們會經常出現對樹形結構的遍歷、查找和轉換的場景,比如說DOM樹、族譜、社會機構、組織架構、許可權、菜單、省市區、路由、標簽等等。那針對這些場景和數據,我們又如何去遍歷和操作,有什麼方式或者技巧可以簡化我們的實現思路。下面我們將針對常規出現的場景去總結一下我們的遍歷方式
樹的特點
1、每個節點都只有有限個子節點或無子節點;
2、沒有父節點的節點稱為根節點;
3、每一個非根節點有且只有一個父節點;
4、除了根節點外,每個子節點可以分為多個不相交的子樹;
5、樹裡面沒有環路
下面的圖片表示一顆樹
在下面的JS中我們由多棵樹組成我們的數據
在這數據中我們如何評判數據是否為葉節點(也就是最後一級),我們每個節點都會存在children屬性,如果不存在children屬性或者children不是一個數組或者children為數組且長度為0我們則認為他是一個葉節點
我們針對樹結構的操作離不開遍歷,遍歷的話又分為廣度優先遍歷、深度優先遍歷。其中深度優先遍歷可以通過遞歸和循環的方式實現,而廣度優先遍歷的話是非遞歸的
從上往下對每一層依次訪問,在每一層中,從左往右(也可以從右往左)訪問結點,訪問完一層就進入下一層,直到沒有結點可以訪問為止。即訪問樹結構的第n+1層前必須先訪問完第n層。
簡單的說,BFS是從根節點開始,沿著樹的寬度遍歷樹的節點。如果所有節點均被訪問,則演算法中止。
所以我們的實現思路是,維護一個隊列,隊列的初始值為樹結構根節點組成的列表,重復執行以下步驟直到隊列為空:
取出隊列中的第一個元素,進行訪問相關操作,然後將其後代元素(如果有)全部追加到隊列最後。
深度優先搜索演算法(英語:Depth-First-Search,DFS)是一種用於遍歷或搜索樹或圖的演算法。這個演算法會盡可能深的搜索樹的分支。當節點v的所在邊都己被探尋過,搜索將回溯到發現節點v的那條邊的起始節點。這一過程一直進行到已發現從源節點可達的所有節點為止。如果還存在未被發現的節點,則選擇其中一個作為源節點並重復以上過程,整個進程反復進行直到所有節點都被訪問為止
1、先序遍歷
訪問子樹的時候,先訪問根再訪問根的子樹
2、後序遍歷
訪問子樹的時候,先訪問子樹再訪問根
1、先序遍歷
先序遍歷與廣度優先循環實現類似,要維護一個隊列,不同的是子節點不追加到隊列最後,而是加到隊列最前面
2、後序遍歷
後序遍歷就略微復雜一點,我們需要不斷將子樹擴展到根節點前面去,執行列表遍歷,並且通過一個臨時對象維護一個id列表,當遍歷到某個節點如羨大果它沒有子節點或者它本身已經存在於我們的臨時id列表,則執行訪問操笑高作,否則繼續擴展子節點到當前節點前面
對於樹結構的遍歷操作,其實遞歸是最基礎,也是最容易理解的。遞歸本身就是循環的思想,所以可以用循環來改寫遞碰派尺歸,以上的方式在項目中已經廊括了大部分的場景了,我們在日常開發中可以根據場景或者需要去選擇我們的遍歷方式,或者基於此對他進行調整和優化,至於每種方式的空間復雜度和時間復雜度我們在這個地方就不去嘗試了,各位感興趣可以自己去驗證。
廣度優先搜索
樹的遍歷
深度優先搜索
圖文詳解兩種演算法:深度優先遍歷(DFS)和廣度優先遍歷(BFS)
二叉樹遍歷(前序,後序,中序,層次)遞歸與迭代實現javaScript
JS樹結構操作:查找、遍歷、篩選、樹和列表相互轉換
㈡ js中數組和對象循環遍歷
數組:
var arr = [『a』,『b』,'c'];
for (let i = 0;i<arr.length;i++){
console.log(i,arr[i])
};
對象:
var person = { name:'tom',age:'29',sex:'男『};
// 對象如果要用for循環來遍歷,需要先有Object.key()的方法來拿到手殲可迭代(遍歷)的私有屬性名的集合(數組)
var keys = Object.keys(person);
for (let i = 0;i<keys.length;i++){
console.log(keys[i]+":"+person[keys[i]]);
};
數組:
for(let key in arr){
// 值得注意的是,key為數組的索引,如若需要獲取屬性的值,則需要使用數組加索引下標 的形式來獲取
console.log(key,arr[key]);
}
對象:
for(let key in obj){
// 值得注意的是,key為對象的鍵名,鍵值要以obj[key]的方式來獲取
console.log(key,obj[key]);
}
數組:
for(let value of arr){
//值得注意的是,for...of跟for...in是不一樣的,for...in遍歷的是數組的索引,for...of遍歷的是數組的值
console.log(value);
}
對象:
for...in是不能單獨來遍歷一個對象的,會報錯。
如果對象是一個類數組對象,那用array.from方法轉成一個數組就可以用for...of來遍歷了。
或者結合Object.keys()方法來使用
for(let key of Object.keys(obj)){
// for...of遍歷輸出的也是鍵名
console.log(key,obj[obj]);
}
數組:
forEach()方法遍歷數組是沒有返回值
值得注意的是數組中有幾項,那麼傳遞進去的匿名回調函數拍啟就需要執行幾次;
arr.forEach((item,index,arr)=>{
console.log(item,index,arr)
)
// 其中item是數組中的當前項,index是數組中的當前下標,arr是原始數組
對象:
原則上forEach是用來遍歷數組的,不能遍歷對象,但是可以用Object.getOnwPropertyNames()方法來使得對象能被forEach遍歷出來。
Object.getOnwPropertyNames()返回一個數組,成員畢賀沖是參數對象自身全部屬性的屬性名,不管該屬性是否能被遍歷。
Object.getOnwPropertyNames(obj).forEach((item,index,arr)=>{
console.log(item,index,obj[item])
})
㈢ javascript遍歷表格中的數據,復雜的嵌套
你好,你的問題藉助jQuery來做很簡單。
//遍歷每個表格
$("table").each(function(i){
//獲取表格第一行
var$tr=$(this).find("tr").first();
//獲取第一行的第2個td列
var$secondTd=$tr.find("td").eq(1);
//獲取目標值
varval=$second.val();
//判讀目標值是否與輸入的值相等,輸入的值用scanner表示
if(val==scanner){
//如果相等,返回第一列值
return$seconTd.prev("td").val();
}
});
㈣ JS幾種數組遍歷方式總結
concat()連接兩個或抄更多的數組,並返回結果。
join()把數組的所有元素放入一個字元串。元素通過指定的分隔符進行分隔。
pop()刪除並返回數組的最後一個元素
push()向數組的末尾添加一個或更多元素,並返回新的長度。
reverse()顛倒數組中元素的順序。
shift()刪除並返回數組的第一個元素。
slice()從某個已有的數組返回選定的元素等等。
㈤ js數組遍歷的常用的幾種方法以及差異和性能優化
<script type="text/javascript">
/*對比:
1、速度比foreach快
2、map會返回一個新數組,不對原數組產生影響,foreach不會產生新數組,foreach返回undefined
3、map因為返回數組所以可以鏈式操作,foreach不能
4, map里可以用return ,而foreach里用return不起作用,foreach不能用break,會直接報錯*/
/*方法一:*/
var arr1 = [1, 2, 3, 4, 5, 6];
for(var i = 0, len = arr1.length; i < len; i++) { //優化性能處理
console.log(arr1[i], 'for遍歷出來的數據'); //每個item 1,2,3,4,5,6
}
/*方法二:*/
/*forEach方法中的function回調支持3個參數,第1個是遍歷的數組內容;第2個是對應的數組索引,第3個是數組本身*/
var arr2 = [{
name: 'bob',
age: 20
},
{
name: 'tom',
age: 18
},
{
name: 'sos',
age: 19
}
]
arr2.forEach((val, i) => { //沒有返回值的,對原來數組也沒有影響
console.log(val, '遍歷出來的每個obj')
});
/*方法三:*/
var fruits = [1, 2, 3, 4, 5, 6, 7, 8];
let arr = fruits.map((item, index) => {
console.log(item, 'top')
console.log(index, 'top')
return item * 8
})
console.log(arr, 'newarr') //[8, 16, 24, 32, 40, 48, 56, 64] "newarr"
var a = fruits.indexOf("Apple", 4);
console.log(a)
//for 和 forEach都是普通循環,map 帶返回值並且返回一個新數組;
/*
*當前元素的值,當期元素的索引值,當期元素屬於的數組對象;
語法:array.map(function(currentValue,index,arr), thisValue)
map() 方法返回一個新數組,數組中的元素為原始數組元素調用函數處理後的值。
map() 方法按照原始數組元素順序依次處理元素。
注意: map() 不會對空數組進行檢測。
注意: map() 不會改變原始數組。
* */
/*方法四:*/
/*兼容寫法:
不管是forEach還是map在IE6 - 8 下都不兼容( 不兼容的情況下在Array.prototype上沒有這兩個方法), 那麼需要我們自己封裝一個都兼容的方法:*/
/**
* forEach遍歷數組
* @param callback [function] 回調函數;
* @param context [object] 上下文;
*/
Array.prototype.myForEach = function myForEach(callback, context) {
context = context || window;
if('forEach' in Array.prototye) {
this.forEach(callback, context);
return;
}
//IE6-8下自己編寫回調函數執行的邏輯
for(var i = 0, len = this.length; i < len; i++) {
callback && callback.call(context, this[i], i, this);
}
}
/**
* map遍歷數組
* @param callback [function] 回調函數;
* @param context [object] 上下文;
*/
Array.prototype.myMap = function myMap(callback, context) {
context = context || window;
if('map' in Array.prototye) {
return this.map(callback, context);
}
//IE6-8下自己編寫回調函數執行的邏輯var newAry = [];
for(var i = 0, len = this.length; i < len; i++) {
if(typeof callback === 'function') {
var val = callback.call(context, this[i], i, this);
newAry[newAry.length] = val;
}
}
return newAry;
}
</script>
㈥ js里怎麼遍歷List
List是java集合對象,js內置對象中並沒有List對象,但是你可以根據js的特性,構造一個List對象,但是基本上可以確定的是js list對象也是依賴於Array,或者是Object對象。
但是個人感覺沒有那個必要,
對於js遍歷java集合對象(list)的話,需要進行一些轉化操作,可以將java中的list對象中的數據通過
json-lib來轉成json。如果再做處理
㈦ js里怎麼遍歷List
代碼如下:
<SCRIPT language="javaScript">
var d = new dTree('d');
d.add(1,-1,"用戶組","","","kunFrame");
<%
Object obj =request.getAttribute("custgrouplist");
List groupList = null;
int count =2;
String groupName = "";
int groupId = 0;
if(obj!=null)
{
groupList = (List)obj;
}
if(groupList!=null&&groupList.size()>0)
{
for(int i=0;i<groupList.size();i++)
{
CustGroup am = (CustGroup)groupList.get(i);
groupName = am.getVgroupName();
groupId = am.getGroupId();
// System.out.println(groupId);
%>
d.add(<%=count%>,1,'<%=groupName%>','<%=request.getContextPath()%>/showAreaByGroup.action?groupId=<%=groupId%>',"","kunFrame");
<%
count++;
}
}
%>
document.write(d);
</SCRIPT>