数组常见的遍历循环方法、数组的循环遍历的效率对比

7次阅读

共计 3346 个字符,预计需要花费 9 分钟才能阅读完成。

1 遍历数组的方法
1-1、for / while
最普通的循环 效率最高 兼容 ie6tips: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 都是兼容 ie9map,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…

正文完
 0