遍历汇总
数组 array
概念:
数组:一组数据的集合。其中每个数据被称为数组的元素。在数组中存放任意类型的数据。数组是将一组数据存储到单个变量名下的方式。
数组声明
三种声明:
1.通过new关键字创建数组。
<script>
var arr = new Array("赵", 2, 3);
console.log(arr); // (3) ["赵", 2, 3]
</script>
2.省略new关键字创建数组
<script>
var arr = Array("字", 2, 3);
console.log(arr);//['字', 2, 3]
</script>
3.字面量赋值
<script>
var arr = ["字", 2, 3];
console.log(arr);//['字', 2, 3]
</script>
【注】前两种方式(new Array-Array),若传入参数只有一个,且为number时,这个数字表示声明的数组的长度,而不是存放的数据。(这种行为叫做创建数组并声明长度)
<script>
var arr = Array(3);
console.log(arr);
</script>
数组的特点
数组的长度(长度从1开始数)
arr.length
<script>
var arr = ["赵", 2, 3];
arr.length = 5;//设置数组的长度
console.log(arr);// ["赵", 2, 3, empty × 2]
</script>
数组的下标
从0开始,数据在数组中的序号。最大值为length-1.
访问数组元素。
格式:数组变量名[下标]
访问数组元素,需要通过下标去访问。(当下标值太大获取的数组里面没有时,
不会报错,返回undefined)
<script>
var arr = ["赵", 2, 3];
console.log(arr[4]);//undefined
</script>
下标可以是任意字符,如果下标是非正整数,我们称之为数组的属性,属性不影响数组的长度
<script>
var arr = [1, "a", "赵"];
arr["ziding"] = "hao";
console.log(arr);// [1, "a", "赵", ziding: "hao"]
console.log(arr.length); //3 长度仍为3,上面加的只是属性
</script>
数组的遍历 (循环)
0到length-1
两种循环遍历方式:
1.普通的for循环。(是通过下标遍历的)
var arr= [10,true,"hello",null,undefined ];
for (var i = 0; i <=arr.length-1; i++) {
document.write(arr[i] + " "); //10 true hello null undefined
}
2.for…in 循环 快速遍历法/快速枚举法
格式:
for (var key in 数组变量名) { }
key指的是下标
<script>
var arr= [10,true,"hello",null,undefined ];
for (var i in arr) {
document.write(arr[i] + " ");
}
</script>
上述两种循环遍历的方法都能够展示如下
(for in遍历能拿到有下标对应的值,拿不到空,但是能拿到里面的属性)
<script>
var arr = ["赵", 2, 3];
arr["zi"] = "hao";//自定义属性
arr.length = 5;
console.log(arr);
for (var i in arr) {
console.log(i);
console.log(arr[i]);
console.log("----------------------");
}
</script>
区别:
1.for in不需要每次都判断,效率更高
2.for in若在遍历过程中,数组发生了变化,会出现问题,不安全。
forEach()遍历(只能用于数组)
格式:数组.forEach(function(item,index)){ }
参数:
item:当前遍历的元素,
index:当前遍历元素的下标
arr:数组
<script>
var arr = [1, 2, 3, 4, 2,true];
arr.forEach(function(item,index) {
document.write("元素:" +item+ " 下标为:" +index+ "<br/>");
})
</script>
三种遍历的总结:
使用数组元素时,
1下标为非负整数(包括整数字符串);
数组[下标]
2下标为负数,小数,非整数字符串时;
数组[属性]
for ------->不遍历属性
foreath ------->不遍历属性和下标中的undefined
for in ------->不遍历下标中的undefined
map()
array.map(function(currentValue,index,arr), thisValue)
创建一个新的数组,其中每一个元素由调用数组中的每一个元素执行提供的函数得来。
forEach()会修改原来的数组。而map()方法会得到一个新的数组并返回,filter()过滤方法也不会改变原数组
<script>
var arr = [50, 86, 12, 10, 0, 38, 12];
arr.map(function(value, index) {
console.log(index + ':' + value); //遍历 index是下标,value是具体的值
})
</script>
var ary = [12,23,24,42,1];
var res = ary.map(function (item,index,input) {
return item*10;
})
console.log(res);//-->[120,230,240,420,10]; 原数组拷贝了一份,并进行了修改
console.log(ary);//-->[12,23,24,42,1]; 原数组并未发生变化
注意 没有办法终止或者跳出forEach()循环,filter可以
<script>
var arr = [{
name: "gao",
age: 10
}, {
name: "jian",
age: 8
}, {
name: "li",
age: 5
}]
function jieh() {
for (var i = 0; i < arr.length; i++) {
if (i == 1) {
return arr[i]
}
}
}
console.log("结果符合", jieh());//{name: 'jian', age: 8}
let jie = arr.filter((item, index, arry) => {
if (index == 1) {
return arry
}
})
console.log("filter符合", jie);//{name: 'jian', age: 8}
let jie1 = arr.forEach((item, index, arry) => {
if (index == 1) {
return arry
}
})
console.log("forEach的情况", jie1);//undefined
let jie2 = arr.map((item, index, arry) => {
if (index == 1) {
return arry
}
})
console.log("map的情况", jie2);//[undefined, Array(3), undefined]
</script>
for > filter > forEach > map–遍历效率超链接
改变数组的方法
<!-- var arr = []
arr.splice() 截取, 新增, 修改,删除
arr.reverse()数组元素反转
arr.sort()数组元素排序
arr.push()末尾添加元素
arr.pop()末尾取下一个元素
arr.unshift()头部添加
arr.shift()头部取下一个元素 -->
some()
array.some``(function(currentValue, index, arr))
some() 方法用于检测数组中的元素是否满足指定条件. 通俗点 查找数组中是否有满足条件的元素
注意它返回值是布尔值, 如果查找到这个元素, 就返回true , 如果查找不到就返回false.
如果找到第一个满足条件的元素,则终止循环. 不在继续查找.
some() 不会改变原始数组。
currentValue: 数组当前项的值
index:数组当前项的索引
arr:数组对象本身
<script>
var arr = [50, 86, 12, 10, 0, 38, 12];
var arr1 = [];
arr.some(function(value, index) {
console.log(index + ':' + value); //遍历 index是下标,value是具体的值
if (value == 12) {
arr1.push(index);
}
})
console.log(arr1); //2
</script>
every()
如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
如果所有元素都满足条件,则返回 true。
every() 不会改变原始数组。
<script>
var arr = [1, 2, 3, 4, 5, 6];
console.log(arr.some(function(item, index, array) {
console.log('item=' + item + ',index=' + index + ',array=' + array);
return item > 3;
}));
console.log(arr.every(function(item, index, array) {
console.log('item=' + item + ',index=' + index + ',array=' + array);
return item > 3;
}));
</script>
如果将上述例子改变为满足item > 3就是下面这种情况
var arr = [ 4, 5, 6];
every()与some()方法都是JS中数组的迭代方法。
some一直在找符合条件的值,一旦找到,则不会继续迭代下去。
every从迭代开始,一旦有一个不符合条件,则不会继续迭代下去。
函数简述
map():返回一个新的Array,每个元素为调用func的结果
filter():返回一个符合func条件的元素数组
some():返回一个boolean,判断是否有元素是否符合func条件
every():返回一个boolean,判断每个元素是否符合func条件
forEach():没有返回值,只是针对每个元素调用func
数组方法
isArray()是Array类型的一个静态方法,可以用于判断一个值是否为数组
方法:
Array.isArray(obj) obj :需要检测的值。
举例:
var a = [1,2,3];
console.log(typeof a); //object
console.log(Array.isArray(a)); //true
去掉vuejs里面数组里的{ob: Observer }方法
JSON.parse()
把json格式的字符串转为js中的数组或对象
JSON.stringify()
把js中的数组或对象转为json字符串
JSON.parse(JSON.stringify(this.list))
push()数组的末尾添加元素
功能:给数组的末尾添加元素
格式:数组名.push(参数…)
返回值:插入元素后的数组长度
var arr = [1,2,"3",true];
arr.push("8");
document.write(arr);
var arr = [1, 2, 3, 4]
var arr2 = arr.push(6)
console.log(arr); //[1, 2, 3, 4,6]
console.log(arr2); //5 返回值是改变后数组的长度
pop()数组的末尾取下一个元素
功能:在数组的末尾取下一个元素
格式:数组名.pop()
返回值:取下的元素。
unshift()头部添加
功能:从数组的头部添加元素
格式:数组名.unshift(参数…)
返回值:插入元素后的数组长度
shift()头部取下一个元素
功能:从数组的头部取下一个元素
格式:数组名.shift()
返回值:取下的元素。
concat()合并数组
功能:合并数组。
格式:数组名.concat(数组);
1.copy原数组,生成新数组。
2.将输入的数组中的元素单独拆分出来,添加到新数组中。
slice()获取当前数组指定区域的元素,生成新数组
功能:获取当前数组指定区域的元素,生成新数组。
格式:数组名.slice(start,end) 含头不含尾
start:开始位置的下标(只有一个值时,表示从这个值开始到结束,包含这个值)
end:结束位置的下标
返回值:新数组,原数组不变。
数组.slice()里面的参数可以是负值,
(下面例子第二个参数为-1时表示数组中最后一个值不在范围)
<script>
var arr = [1, 2, 3, 4, 5, 6];
var arr2 = arr.slice(0,-1);
console.log(arr2);// 输出 [1, 2, 3, 4, 5]
</script>
substring() 方法和slice()方法类似,区别是
substring() 方法不接受负的参数
substring和substr的区别
substring是获取从start位开始到end位之间的字符串,而substr是获取从start位开始后end位的字符串;(两种方法都包含start位的字符串,区别在于ubstring不包含end位的字符串,substr包含)
例:
var mystring="Hello world!";
substring(2,4);//输出“ll”(遵循含头不含尾)
substr(2,4);//输出“llo ” (注意截取的字符串后有空格,从第二位开始截取,包空格共4个字符的字符串)
splice()截取, 新增, 修改,删除
截取
格式:数组.splice(start,length,数据…)
返回值:截取的元素
参数:
start:开始截取的位置
length:截取的长度
第三个参数开始:在start位置开始,插入新元素。
对数组元素的
新增
arr.splice(4,0,“5”);
修改
arr.splice(2,1,4);
删除
arr.splice(2,1);
<script>
var str = [1, 2, 3, 4, 5];
/* var str2 = str.splice(6, 0, 6);添加
console.log(str);// [1, 2, 3, 4, 5, 6]*/
/* var str2 = str.splice(4, 1);删除
console.log(str); // [1, 2, 3, 4]*/
var str2 = str.splice(0, 1, 9);//更改
console.log(str); // [9, 2, 3, 4, 5]*/
</script>
delete 数组 删除数组元素
<script>
var arr = [{
msg: "数据1"
}, {
msg: "数据2"
}, {
msg: "数据3"
},]
delete arr[1];
console.log(arr);
</script>
delete会删除数组的值,但是它依然会在内存中占位置
join()拼接字符串
格式:数组.join(字符串); 不改变原数组
功能:将数组中元素用指定的字符串拼接
返回值:拼接好的字符串(这种行为可以把数组转成字符串)
reverse()数组元素反转
功能:将数组元素反转。
格式:数组.reverse();
该方法会修改原数组。
sort()数组元素排序
对数组中的元素进行排序
数组的排序
sort:按照Unicode编码比较,类似字符串的比较方式。
var arr = [1,15,2,23];
当有 两位数时就要这样排
arr.sort(function(value1,value2){
// 从小到大
// return value1 - value2;
// 从大到小。
return value2 - value1;
});
alert(arr);//[23, 15, 2, 1]
---------------ES5新增常见方法----------------------------------------------
indexof()查找第一次出现元素的下标
功能:在数组中查找第一次出现元素的下标。
格式:数组.indexOf(item,start);
参数:
item:要查找的元素
start:开始查找的位置
返回值:查找到的元素下标,若未查到,则返回-1。
小记:search()和index的区别是:区别是search能用正则表达式匹配
js中includes()、indexOf()、search()、match()几种方法的区别
lastIndexOf() :
从后往前遍历查找对应字符串,找到对应字符串结束返回数据,返回值为int类型,返回查找字符串首个字符位置(从0开始查找),未找到返回 -1;
var str = "123456321";
console.log(str.indexOf(3)); //2
console.log(str.lastIndexOf(3));//6
可以看到是从后往前查找第一次出现的下标位置,(这个第一次是正着数的第一次)
所以得出6(3第一次出现倒着数的位置是6);
filter()
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
array.filter(function(currentValue,index,arr), thisValue)
例如:过滤数组中的偶数
let arr = [1, 2, 3, 4, 5, 6];
// 方式一
let newArr = arr.filter((value, index, array) => {
if(value % 2 === 0) {
return value
}
});
console.log(newArr);// [ 2, 4, 6 ]
// 方式二
newArr = arr.filter((item) => item % 2 === 0);
//newArr = arr.filter(function(item) {
// return item % 2 === 0
// });
console.log(newArr);// [ 2, 4, 6 ]
实例:根据id删除数组中的对象方法
//使用过滤器筛选出id不等于要删除的数据的所有对象,并将其重新赋值给list数组
this.list = this.list.filter((item) => {
return item.id != id
});
- filter和find()区别
1、filter返回的是数组,find返回的是对象。
2、find()找到第一个元素后就不会在遍历其后面的元素,所以如果数组中有两个相同的元素,他只会找到第一个,第二个将不会再遍历了。
let findObject = Num.find((n) => n.value < 3)
let filterArry = Num.filter((n) => n.value < 3)
console.log("findObject", findObject);
console.log("filterArry", filterArry);
find() 和 findIndex()
数组实例的find方法,用于找出第一个符合条件的数组成员。
它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,
然后返回该成员。
如果没有符合条件的成员,则返回undefined。
[1, 4, -5,-3, 10].find((n) => n < 0)
// -5
find方法的回调函数可以接受三个参数,依次为
当前的值、
当前的位置
原数组。
var str = [1, 5, 10, 15]
str.find(function(value, index, arr) {;
// return console.log(value);
// return console.log(index);
// return console.log(arr);
})
findIndex()
findIndex()方法返回第一个符合条件的数组成员的位置(数组的下标),如果所有成员都不符合条件,则返回-1,和arr.indexOf()类似
[1, 5, 10, 15].findIndex(function(value, index, arr) {
return value > 9;
}) // 2
这两个方法都可以接受第二个参数,用来绑定回调函数的this对象。
function f(v){
return v > this.age;
}
let person = {name: 'John', age: 20};
[10, 12, 26, 15].find(f, person); // 26
上面的代码中,find函数接收了第二个参数person对象,回调函数中的this对象指向person对象。
另外,这两个方法都可以发现NaN,弥补了数组的indexOf方法的不足。
// var arr2 = [NaN].indexOf(NaN);
console.log(arr2);//-1
//Object.is()-----判断是否全等,和===一样
var arr2 = [NaN].findIndex(y => Object.is(NaN, y));
// var arr2 = [NaN].findIndex(function(y) {
// return Object.is(NaN, y)
// });
console.log(arr2); //0
上面代码中,indexOf方法无法识别数组的NaN成员,但是findIndex方法可以借助Object.is方法做到
includes() Es7
includes() 方法用于判断字符串是否包含指定的子字符串。
如果找到匹配的字符串则返回 true,否则返回 false。
注意: includes() 方法区分大小写。
string.includes(searchvalue, start)
如果存在会返回查找值的位置,找不到会返回-1;但是这有个问题就是,如果查找的值碰巧是NaN呢:
就会返回-1,这不是我们想要的结果,再来看看includes()方法可以做到吗:
includes()方法正确的判断了NaN是否存在,而indexOf()不行。
比较:
1,使用方法基本一样
2,初衷都是查看数组是否包含某个值
3,indexOf没有includes语义化更强
4,includes更加完善
reduce和reduceRight
reduce解说:https://www.jianshu.com/p/e375ba1cfc47
reduce(),是从数组的第一项开始,一项一项的遍历,直到最后一项;
reduceRight(),从数组的最后一项开始遍历,直到第一项;
语法:arr.reduce(callback,[initialValue])
callback (执行数组中每个值的函数,包含四个参数)
1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
2、currentValue (数组中当前被处理的元素)
3、index (当前元素在数组中的索引)
4、array (调用 reduce 的数组)
initialValue (作为第一次调用 callback 的第一个参数。)
<script>
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var sum0 = 0;
for (let index = 0; index < arr.length; index++) {
sum0 = sum0 + arr[index];
}
console.log(sum0) //55
const arr1 = [1, 2, 3];
const sum = arr1.reduce((pre, cur, index, arr) => {
console.log(pre, cur);
//console.log(index) // 012
//console.log(arr) //数组对象
return pre + cur //实现累计效果,第一次循环的结果作为第二次循环的初始条件,pre就是每次累计的结果值
}, 100);
// console.log(sum) // 6 如果没有提供initialValue,reduce 会从索引1的地方开始执行 callback 方法
console.log(sum) // 106 (如果设置初始值100)
const sum1 = arr.reduceRight((pre, cur, index, arr) => {
console.log(index) //876543210
return pre + cur
})
console.log(sum1)//55
</script>
二维数组
二维数组:数组中的元素为数组是,该数组被称为二维数组。
var arr = new Array(["韩信", 20, "打野"], ["鲁班", 9, "射手"], ["不知火舞", 24, "法师"]);
arr[1][1] = 10;
alert(arr);
冒泡排序
铺垫:a的值和b的值互换,要有第三个变量
var a = 1;
var b = 2;
var c = a;//这算是把a的值让c存下
a = b;//对a重新赋值,把b的值给a
b = c;//对b重新赋值,把c的值(其实就是a的值)给b
console.log("a值", a, " b值", b); //a值2 b值1
var arr = [7, 3]
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {//如果下一个相邻的数大于前一个数
var temp = arr[j]; //转换位置就像2个杯子倒水,要有第三个杯子
console.log("数据3", temp);
arr[j] = arr[j + 1]; //就转换位置(重点1)
console.log("数据1转换后", arr[j]);
arr[j + 1] = temp; //重点2
console.log("数据2转换后", arr[j + 1]);
}
}
}
console.log("排序后数据", arr);//[3,7]
<script>
// 规则:从左到右,数组中相邻的两个元素进行比较。将较大(较小)的数放在后面。
// 规律:每一轮都可以找出一个最大(最小)值,放在正确的位置上。
// 比较的轮次:数组的长度-1
// 每一轮比较的次数:数组长度-当前的轮次
var arr = [5, 4, 7, 2, 9, 1, 6];
for (var i = 0; i < arr.length-1; i++) {
for (var j = 0; j < arr.length-1-i; j++) {
if (arr[j]>arr[j+1]) {
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
console.log("每一轮", arr);
}
console.log("冒泡排序", arr);
</script>
选择排序
<script>
//规则:选出一个位置,让这个位置上的数与后面的数比较,如果大于(小于)后面的数,则交换位置
,然后对该位置进行下一轮比较。
// 规律:每一轮,在当前位置找到正确的值。
//比较的轮次:数组的长度-1
// 每一轮比较的次数:数组长度-当前的轮次
var arr = [5, 4, 7, 2, 9, 1, 6];
for (var i = 0; i < arr.length - 1; i++) {
for (var j = i+1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
var temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
console.log("每一轮1", arr);
}
</script>
区别:
冒泡排序是比较相邻的两个数。而选择是按照位置比较,不一定相邻。