陣列常見的遍歷迴圈方法、陣列的迴圈遍歷的效率對比

sillyhong發表於2019-02-17

1 遍歷陣列的方法

1-1、for / while

最普通的迴圈 效率最高 相容ie6
tips:for迴圈更適用於迴圈的開始和結束已知,迴圈次數固定的場合;while迴圈更適合於條件不確定的場合

1-2、for in

相容ie6,效率最差(效率可看最下面的對比) for in 會把繼承鏈的物件屬性都會遍歷一遍,所以會更花時間.

var arr = [`red`, `green`, `blue`];
var obj = {
    name:`張三`,
    age:20
}
 
<!-- 迴圈物件 -->
for(k in obj){
    console.log(k); //name  , age 
    console.log(obj[k]);  // 張三 , 20
}
 
<!-- 迴圈陣列 -->
for(k in arr){
    console.log(k);   // 0   , 1   ,2  
    console.log(arr[k]); // red, green ,blue
}

1-3、for of  es6語法

ie不相容  【for-of 語句只遍歷可迭代物件的資料。】原生具備 Iterator 介面的資料結構如下。ArrayMapSetStringTypedArray函式的 arguments 物件NodeList 物件更多迭代器 閱讀:http://es6.ruanyifeng.com/#do…

var arr = [`red`, `green`, `blue`];
 
for(var v of arr) {
    console.log(v); // red green blue
}

區別:for of 和 for in的區別for-in 語句以原始插入順序迭代物件的可列舉屬性。for-in會把繼承鏈的物件屬性都會遍歷一遍,所以會更花時間.

2、陣列自帶的迴圈方法:

every 、 filter、forEach、map、reduce、some 都是相容ie9
map,filter 是返回新的陣列 (形象區分幾個迴圈方法的區別參考:https://www.zhihu.com/questio…

2-1、Array.prototype.every()

方法說明:測試陣列的所有元素是否都通過了指定函式的測試。 遇到有不滿足的會提前終止整個迴圈
場景:檢測每一項的selected欄位都是被選中為true
案例:

var arr = [
    {id:1,name:"zhangsan1",selected:false},
    {id:2,name:"zhangsan2",selected:false},
    {id:3,name:"zhangsan3",selected:true},
];
 
 
var reslut = arr.every(function(el,index,arr){
    console.log(el);
    return el.selected==true;
});
 
console.log(reslut);  //false

2-2、Array.prototype.filter()  

方法說明: 將所有在過濾函式中返回 true 的陣列元素放進一個新陣列中並返回。true表示保留該元素(通過測試),false則不保留
場景:在一個陣列中篩選數字大於10的元素,組成一個新陣列
案例:

var arr = [
    10,20,30
];
 
var arr1 = arr.filter(function(el,index,arr){
    return el > 10;
});
 
console.log(arr1);  // 20 30

2-3、Array.prototype.forEach()
 
方法說明:方法對陣列的每個元素執行一次提供的函式    沒有辦法中止或者跳出 forEach 迴圈,除了丟擲一個異常。 如果您正在測試一個陣列裡的元素是否符合某條件,且需要返回一個布林值,那麼可使用 Array.every 或 Array.some。如果可用,新方法 find() 或者findIndex() 也可被用於真值測試的提早終止。
場景: 普通遍歷
案例:

var arr = [
    {id:1,name:"zhangsan1",selected:false},
    {id:2,name:"zhangsan2",selected:false},
    {id:3,name:"zhangsan3",selected:true},
];
 
 
arr.forEach(function(el,index,arr){
    console.log(el)
});

2-4、Array.prototype.map()
方法說明:方法建立一個新陣列,其結果是該陣列中的每個元素都呼叫一個提供的函式後返回的結果。
場景:非同步得到資料後,需要新建一個資料根據id標識記錄是否被選中的selected屬性
案例:

var arr = [
    {id:1,name:"zhangsan1"},
];
 
var arr1 = arr.map(function(el,index,arr){
    var newObj = {};
    newObj.id = el.id;
    newObj.selected = false;
    return newObj;
});
 
console.log(arr);  // [{id:1,name:"zhangsan1"}]
console.log(arr1);  // [{id:1,selected:false}]

案例2: es6寫法

var numbers = [1, 5, 10, 15];
var doubles = numbers.map( x => x ** 2); //[2,10,20,30]

案例3:重格式化陣列 //不改變原陣列

var kvArray = [{key: 1, value: 10}, 
               {key: 2, value: 20}, 
               {key: 3, value: 30}];
 
var reformattedArray = kvArray.map(function(obj) { 
   var rObj = {};
   rObj[obj.key] = obj.value;
   return rObj;
});
 
// reformattedArray 陣列為: [{1: 10}, {2: 20}, {3: 30}], 

2-5、Array.prototype.reduce()

方法說明:方法對累加器和陣列中的每個元素(從左到右)應用一個函式,將其減少為單個值。
場景:累加 、 合併多個陣列
案例:

var total = [0, 1, 2, 3].reduce(function(sum, value) {
  return sum + value;
}, 0);
// total is 6
 
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) {
  return a.concat(b);
}, []); 
// flattened is [0, 1, 2, 3, 4, 5]

2-6、Array.prototype.some()

方法說明:方法測試陣列中的某些元素是否通過由提供的函式實現的測試。
場景:檢查陣列中是否含有某個東西 (和every 是對立的)
案例:

const isBiggerThan10 = (element, index, array) => {
  return element > 10;
}
 
[2, 5, 8, 1, 4].some(isBiggerThan10);  
// false
 
[12, 5, 8, 1, 4].some(isBiggerThan10); 
// true

案例2: 是否包含id為1 物件

var arr = [
    {id:1,name:"zhangsan1"},
    {id:2,name:"zhangsan2"},
];
 
 
var flag = arr.some(function(element, index, array){
    console.log(element.id)
    return element.id == 1;
});  
 
console.log(flag)

3、 迴圈/遍歷效率對比

for ~= do while < forEach ~= map ~= every < $.each < $(e).each < for in  
參考:http://www.jb51.net/article/1…

for > for-of > forEach > filter > map > for-in
參考:https://dailc.github.io/2016/…

4、原生實現every 、 filter、forEach、map、reduce、some 等方法

 http://www.jb51.net/article/6…

5、其他參考

https://juejin.im/post/5a3a59…

相關文章