js数组循环的几种方式,区别是什么?

656 阅读11分钟

转载链接:blog.csdn.net/u010047432/…
www.jiangweishan.com/article/js8…

JS中遍历数组的函数有: for、for...in...、forEach、some、map、filter、every
ES6中遍历数组的api有:forEach()、map()、include()、indexOf()、filter()、some()、every()
可用于对象(数组)合并、去重的Set对象

1.for和for in
for循环是写js常使用到的
基本语法:

for (语句 1; 语句 2; 语句 3)
  {
      被执行的代码块
  }

语句 1 在循环(代码块)开始前执行
语句 2 定义运行循环(代码块)的条件
语句 3 在循环(代码块)已被执行之后执行

例子:

for (var i=0; i<5; i++)
  {
      x=x + "The number is " + i + "<br>";
  }

从上面的例子中,您可以看到:
1 在循环开始之前设置变量 (var i=0)。
2 定义循环运行的条件(i 必须小于 5)。
3 在每次代码块已被执行后增加一个值 (i++)。

2.for...in... 用于循环对象属性
基本语法:

for (var in object) {
 执行的代码块
}

var person = {fname:"John", lname:"Doe", age:25}; 
var text = "";
var x;
for (x in person) {
    text += person[x];
}
 
结果:
John Doe 25

ES6中写for循环:
for (let i in arr)
for (const v of arr)

3.forEach()
forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。
forEach()遍历方法遍历数组全部元素,利用回调函数对数组进行操作,自动遍历数组,且无法通过break中途跳出循环,不可控、不支持return操作输出,return只用于控制循环是否跳出当前循环

注意: forEach() 对于空数组是不会执行回调函数的。

基本语法:

array.forEach(function(currentValue, index, arr), thisValue)

image.png

ES6中调用forEach():

 let totalPrice = 0,
      totalNum = 0,
      allCheckd = true;
    cart.forEach(v => {
      if (v.checked) {
        totalPrice += v.goods_price * v.num;
        totalNum += v.num;
      } else {
        allCheckd = false;
      }
    });
    //callback使用箭头函数

4.some() 相应链接:blog.csdn.net/qq_40190624…
some 英语翻译为一些,所以some方法 只要其中一个为true 就会返回true的,every()和 some()目的:确定数组的所有成员是否满足指定的测试
some:一真即真

例子:

/** 
 * 计算对象数组中每个电脑的扣件系统是否可用,大于16位操作系统表示可用,否则不可用
*/
var computers = [
    {name:"Apple",ram:8},
    {name:"IBM",ram:4},
    {name:"Acer",ram:32},
];
 var result= computers.every(function(computer){
   return computer.ram > 16
})
console.log(result)//false;
var some = computers.some(function(computer){
   return computer.ram > 16
})
console.log(some)//true;
原文链接:https://blog.csdn.net/qq_40190624/article/details/82533610

5.every() 相应链接:blog.csdn.net/qq_40190624…
every翻译为所有,每个,every()方法必须所有都返回true才会返回true,哪怕有一个false,就会返回false;every()和 some()目的:确定数组的所有成员是否满足指定的测试
every:一假即假

例子:

//判断对象数组中每个人是否成年,大于17成年,否则未成年
var arr = [
            {name:'jerry',sex:'man',age:14},
            {name:'jack',sex:'woman',age:19},
            {name:'bill',sex:'man',age:18}
        ]
        var every = arr.every(function(obj){  //every  一假即假
            return obj.age > 17   
        })
        var some = arr.some(function(obj){   // some  一真即真
            return obj.age >17
        })
        console.log(every,some)  //false  true

6.map()
map()根据当前数组映射出一个新的数组,map和forEach等遍历方法不同,在forEach中return语句是没有任何效果的,而map则可以改变当前循环的值,返回一个新的被改变过值之后的数组(map需return),一般用来处理需要修改某一个数组的值 [map()循环数组,可以改变原数组的值,并返回一个被改变过值的新数组,但map()要return]

例子:

let arr1 = [1,2,3];
let arr2 = arr1.map((value,key,arr) => {
    console.log(value)    // 1,2,3
    console.log(key)      // 0,1,2
    console.log(arr)      //[1,2,3] [1,2,3] [1,2,3]  有若干个值 就会遍历若干个自身的数组 
    return value * value;
})
console.log(arr1); // [ 1, 2, 3 ]
console.log(arr2); // [ 1, 4, 9 ]

原文链接:https://blog.csdn.net/weixin_44223007/article/details/98479489

也可以遍历对象:

let products= [
			{ name: "马云", price: 200 },
			{ name: "马化腾", price: 140 },
			{ name: "马冬梅", price: 20 },
			{ name: "马某", price: 10 }
		]
var newProducts= products.map(product => {
		return {
			// 改变循环的值 得到一个新的数组 
			name: "**" + product.name + "**",
			price: product.price / 2
		};
});
console.log(newProducts)
/*
0: {name: "**马云**", price: 100}
1: {name: "**马化腾**", price: 70}
2: {name: "**马冬梅**", price: 10}
3: {name: "**马某**", price: 5}
*/
原文链接:https://blog.csdn.net/weixin_44223007/article/details/98479489

7.filter()
filter()方法,用来过滤数组,返回一个新的数组,filter方法需要在循环的时候判断一下是true还是false,是true才会这个元素

例子:

let arr1 = [1,2,3];
let arr2 = arr1.filter((value,key,arr) => {
    console.log(value)    // 1,2,3
    console.log(key)      // 0,1,2
    console.log(arr)      // [1,2,3]
    return value >= 3 ? false : true;     
})
console.log(arr1); // [ 1, 2, 3 ]
console.log(arr2); // [ 1, 2 ]

原文链接:https://blog.csdn.net/weixin_44223007/article/details/98479489

filter()可以用来去除不符合的数组元素

let arr = [1,2,3]
let newArr = arr.filter(item => item>=3)  
console.log(newArr)// [3]

filter()去掉空字符串、undefined、null

let arr = ['','1','2',undefined,'3.jpg',undefined]
let newArr = arr.filter(item => item)
console.log(newArr) //  arr=['1','2','3.jpg']

filter数组去重的操作

let arr = [1, 2, 2, 3, 4, 5, 5,5, 6,6,6,6];
let newArr = arr.filter((x, index,self)=>self.indexOf(x)===index) 
console.log(newArr)

filter()筛选数组对象

let arr = [
	    {a:'苹果',b:'面包',c:'吃'},
	    {a:'香蕉',b:'面包',c:'不吃'},
	    {a:'香蕉',b:'苹果',c:'吃'},
	    {a:'苹果',b:'香蕉',c:'不吃'},
	  ]
console.log(arr.filter(item => item.a=== '苹果' ))
//[{a:'苹果',b:'面包',c:'吃'},{a:'苹果',b:'香蕉',c:'不吃'}]

注意:如果是多个条件的筛选的话,可以在item后加上这样类型的判断

item => (a?item.a === a : true) && (b?item.b === b : true) && (c?item.c === c : true)

a和b和c的值都是需要我们提前预设的

8.indexOf() 转载链接:www.jianshu.com/p/14635c245…
indexOf()方法可返回某个指定的字符串值在字符串中首次出现的位置,如果没有找到返回-1

indexOf()只返回字符串在规定的查找顺序中,首次出现的位置
工作中应用 => 如果要检索的字符串值没有出现,则该方法返回-1

  1. 语法
stringObject.indexOf(searchvalue,fromindex)

// 该方法将从头到尾地检索字符串 stringObject,看它是否含有子串 searchvalue。
// 开始检索的位置在字符串的 fromindex 处或字符串的开头(没有指定 fromindex 时)。
// 如果找到一个 searchvalue,则返回 searchvalue 的第一次出现的位置。
// stringObject 中的字符位置是从 0 开始的

2.indexOf() 方法在数组和字符串的具体使用
该方法返回某个元素在字符串中或数组中的位置
(1)对string类型的使用

let str = 'orange';
 
str.indexOf('o'); //0
str.indexOf('n'); //3
str.indexOf('c'); //-1

(2)对array类型的使用

array.indexOf(item,start)
返回元素在数组中的位置,若没检索到,则返回 -1。
参数 描述
item 必须。查找的元素
start 可选。规定检索的位置,它的合法取值是 0 到 stringObject.length - 1

例子:

let arr = ['orange', '2016', '2016'];
 
arr.indexOf('orange'); //0
arr.indexOf('o'); //-1

var arr = [1,2,3];
console.log(arr.indexOf(1));//0
console.log(arr.indexOf(2));//1
console.log(arr.indexOf(3));//2
console.log(arr.indexOf(4));//-1

找数组中的元素,也可以使用es6的find()方法

(3)对number类型无法使用

let num = 2016;
 
num.indexOf(2); //Uncaught TypeError: num.indexOf is not a function

如果一定要对number类型使用这个方法的话,那就要把值转换成字符串
例子:

//简单
num = '2016';
num.indexOf(2); //0

//一般
num.toString().indexOf(2); //0

//最简洁
('' + num).indexOf(2); //0

3.使用indexOf()对数组进行去重
例子:

//写法一
var newArr =  [ ];
 arr.forEach(function(v){ // 使用forEach循环遍历,获取原始数组arr中的所有数值
            // 在新数组中,查找当前获取的原始数组的数值
            // newArr.indexOf(v) 执行结果如果是 -1
            // 证明在新数组中,没有这个原始数组的数据
 newArr.indexOf(v) 
    if(newArr.indexOf(v) === -1){
              // 将这个数据,写入到新数组中
                newArr.push(v)
            }
        })
        console.log( newArr );

// 写法二 
var arr = ['C','A','A','G','G','G','D']
        var newArr = []
        arr = arr.sort(function(a,b){
            return a > b
        }).forEach(function(n){
            if(newArr.indexOf(n) == -1){
                newArr.push(n)
            }
        })
        console.log(newArr);// ["A", "C", "D", "G"]

// 写法三
var arr = ['a','c','b','d','a','b']
        var arr2 = [];
        for(var i = 0;i<arr.length;i++){
            if(arr2.indexOf(arr[i])<0){
                arr2.push(arr[i]);
            }
        }
        arr2.sort();
        console.log(arr2);//["a", "b", "c", "d"]
        //sort()方法是对数组进行排序的方法
        //链接:https://www.w3school.com.cn/js/jsref_sort.asp

9.findIndex() 链接:m.runoob.com/jsref/jsref…
1.语法

array.findIndex(function(currentValue, index, arr), thisValue)

image.png

2.定义和用法
(1)findIndex() 方法返回传入一个测试条件(函数)符合条件的数组第一个元素位置。
(2)findIndex() 方法为数组中的每个元素都调用一次函数执行:

  1. 当数组中的元素在测试条件时返回 true 时, findIndex() 返回符合条件的元素的索引位置,之后的值不会再调用执行函数。
  2. 如果没有符合条件的元素返回 -1

注意: findIndex() 对于空数组,函数是不会执行的。
注意: findIndex() 并没有改变数组的原始值。[不会改变原数组]

例子:

const bookArr=[
    {
        id:1,
        bookName:"三国演义"
    },
    {
        id:2,
        bookName:"水浒传"
    },
    {
        id:3,
        bookName:"红楼梦"
    },
    {
        id:4,
        bookName:"西游记"
    }
];
var i=bookArr.findIndex((value)=>value.id==4);
console.log(i);// 3
var i2=bookArr.findIndex((value)=>value.id==100);
console.log(i2);// -1

10.find() 链接:www.jianshu.com/p/1c15be16a…
该方法主要应用于查找第一个符合条件的数组元素。它的参数是一个回调函数。在回调函数中可以写你要查找元素的条件,当条件成立为true时,返回该元素。如果没有符合条件的元素,返回值为undefined。

例子:

//在myArr数组中查找元素值大于4的元素,找到后立即返回。返回的结果为查找到的元素
const myArr=[1,2,3,4,5,6];
var v=myArr.find(value=>value>4);
console.log(v);// 5

//没有符合元素,返回undefined
const myArr=[1,2,3,4,5,6];
var v=myArr.find(value=>value>40);
console.log(v);// undefined

回调函数有3个参数。value:当前的数组元素。index:当前索引值。arr:被查找的数组

例子:

//查找索引值为4的元素
const myArr=[1,2,3,4,5,6];
var v=myArr.find((value,index,arr)=>{
    return index==4
});
console.log(v);// 5

注意:find() 对于空数组,函数是不会执行的
注意:find() 并没有改变数组的原始值

11.include() 链接:www.jb51.net/article/124…

在ES5,Array已经提供了indexOf用来查找某个元素的位置,如果不存在就返回-1,但是这个函数在判断数组是否包含某个元素时有两个小不足,第一个是它会返回-1和元素的位置来表示是否包含,在定位方面是没问题,就是不够语义化。另一个问题是不能判断是否有NaN的元素。

例子:

const arr1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', NaN]
console.log('%s', arr1.indexOf(NaN))
//结果:-1

ES6提供了Array.includes()函数判断是否包含某一元素,除了不能定位外,解决了indexOf的上述的两个问题。它直接返回true或者false表示是否包含元素,对NaN一样能有有效。【判断数组中是否有对应的元素,不能进行元素定位,但可以判断NaN,有对应元素则返回true,没有则返回false】

例子:

const arr1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', NaN]
console.log('%s', arr1.includes('c'))//true
console.log('%s', arr1.includes('z'))//false
console.log('%s', arr1.includes(NaN))//true

//includes()函数的第二个参数表示判断的起始位置。
const arr1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', NaN]
console.log('%s', arr1.includes('d', 1))//true
console.log('%s', arr1.includes('d', 3))//true
console.log('%s', arr1.includes('d', 4))//false

//第二个参数也可以是负数,表示从右数过来第几个,但是不改变判断搜索的方向,搜索方向还是从左到右
console.log('%s', arr1.includes('k', -1))//false
console.log('%s', arr1.includes('k', -2))//true
console.log('%s', arr1.includes('i', -3))//false

12.set() 可用于对象(数组)合并,去重 链接:www.cnblogs.com/mahmud/p/10…
ES6中的set()可以实现在返回的一串数据的数组中挑选出满足你条件的数据【可以进行数据去重!!!】

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set 本身是一个构造函数,用来生成 Set 数据结构。

1.数组去重
image.png
[...new Set(arr)]是解构数组,将arr中不重复的元素存储到unique数组中

2.字符去重
image.png

另外 Set 是如此强大,因此使用 Set 可以很容易地实现并集(Union)、交集(Intersect)和差集(Difference)。

MDN中set()解释:developer.mozilla.org/en-US/docs/…

13.Array.from()
方法可以将 Set 结构转为数组。我们可以专门编写使用一个去重的函数

image.png

转载链接:www.cnblogs.com/jf-67/p/844…

Array.from()方法就是将一个类数组对象或者可遍历对象转换成一个真正的数组。

那么什么是类数组对象呢?所谓类数组对象,最基本的要求就是具有length属性的对象。

1.将类数组对象转换成真正数组:

let arrayLike = {
    0: 'tom', 
    1: '65',
    2: '男',
    3: ['jane','john','Mary'],
    'length': 4
}
let arr = Array.from(arrayLike)
console.log(arr) // ['tom','65','男',['jane','john','Mary']]

那么,如果将上面代码中length属性去掉呢?实践证明,答案会是一个长度为0的空数组。

这里将代码再改一下,就是具有length属性,但是对象的属性名不再是数字类型的,而是其他字符串型的,代码如下:

let arrayLike = {
    'name': 'tom', 
    'age': '65',
    'sex': '男',
    'friends': ['jane','john','Mary'],
    length: 4
}
let arr = Array.from(arrayLike)
console.log(arr)  // [ undefined, undefined, undefined, undefined ]

会发现结果是长度为4,元素均为undefined的数组

重点:由此可见,要将一个类数组对象转换成一个真正的数组,必须具备以下条件:
1.该类数组对象必须具有length属性,用于指定数组的长度。如果没有length属性,那么转换后的数组是一个空数组。
2.该类数组对象的属性名必须为数值型或字符串型的数字
注意: 该类数组对象的属性名可以加引号,也可以不加引号

2.将Set结构的数据转换为真正的数组:

let arr = [12,45,97,9797,564,134,45642]
let set = new Set(arr)
console.log(Array.from(set))  // [ 12, 45, 97, 9797, 564, 134, 45642 ]  

Array.from还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。如下:

let arr = [12,45,97,9797,564,134,45642]
let set = new Set(arr)
console.log(Array.from(set, item => item + 1)) // [ 13, 46, 98, 9798, 565, 135, 45643 ]

3.将字符串转换为数组:

let  str = 'hello world!';
console.log(Array.from(str)) // ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d", "!"]

4.Array.from参数是一个真正的数组:

console.log(Array.from([12,45,47,56,213,4654,154]))

第4种情况,Array.from会返回一个一模一样的新数组