1.数组循环
参数 val : 数组元素 , index:元素索引,arr:原数组本身
arr.forEach( function( val, index, arr ){ } ) // 没有返回值,undefiend
let arr = ["red","blue","green"]
let arr2 = arr.forEach(function(val,index,arr){
console.log(val,index,arr)
})
red 0 ["red","blue","green"]
blue 1 ["red","blue","green"]
green 2 ["red","blue","green"]
注:forEach是没有返回值的
console.log(arr2 ) // undefiend
arr.map( function( val, index, arr ){ return } ) // 有返回值,返回的是一个新数组
一般用于数据的映射(数据改造),正常情况下需要配合return使用。如果不使用return,那么他的功能和forEach一模一样,就没必要使用map,所以只要使用map,一定要有return。
有return
let arr = [
{name:"张三",age:20,sex:"男"},
{name:"张三",age:10,sex:"男"},
{name:"张三",age:8,sex:"男"}
];
let arr1 = arr.map( function(item, index, arr ){
let obj = {};
obj.NAME = item.name
obj.AGE = item.age
obj.SEX = item.sex
return obj
})
console.log(arr1)
结果如下:
[
{NAME :"张三",AGE :20,SEX :"男"},
{NAME :"张三",AGE :10,SEX :"男"},
{NAME :"张三",AGE :8,SEX :"男"}
]
-----------------------------------------------------------
没有return,则默认返回的是undefiend
let arr1 = arr.map( function(item, index, arr ){
console.log(item,index,arr )
})
console.log(arr1 )
结果如下:
[undefiend,undefiend,undefiend]
arr.filter( function( val, index, arr ){ } ) // 过滤不合格的数据,返回合格数据组成的新的数组
let arr = [
{name:"张三",age:20,sex:"男"},
{name:"张三",age:10,sex:"男"},
{name:"张三",age:8,sex:"男"}
];
let arr1 = arr.filter( function(item, index, arr ){
// 过滤掉age<10的数据
return item.age>=10
})
console.log(arr1)
结果如下:
[
{name:"张三",age:20,sex:"男"},
{name:"张三",age:10,sex:"男"}
]
arr.some( function( val, index, arr ){ } ) // 数组中某一个元素符合条件,就整体返回true,否则返回false
arr.every( function( val, index, arr ){ } ) // 数组中每一个元素都符合条件,就整体返回true,否则返回false
some,every类似查找的功能
let arr = [
{name:"张三",age:20,sex:"男"},
{name:"张三",age:10,sex:"男"},
{name:"张三",age:8,sex:"男"}
];
let arr1 = arr.some( function(item, index, arr ){
return item.age>=20 // 有一个满足条件
})
console.log(arr1) // true
let arr1 = arr.some( function(item, index, arr ){
return item.age>=30 // 都不满足条件
})
console.log(arr1) // false
let arr1 = arr.every( function(item, index, arr ){
return item.age>=20 // 只有一个满足条件
})
console.log(arr1) // false
let arr1 = arr.every( function(item, index, arr ){
return item.age>=8 // 都满足条件
})
console.log(arr1) // true
注:上面的forEach、map、filter、some几个方法实际上是可以接受两个参数,第一个是回调函数,第二个是希望this指向谁:
let arr = ["red","blue","green"]
arr.map( function( val, index, arr ){ return } )
arr.forEach(function(val,index,arr){
console.log( this,val,index,arr) // 默认this指向 window
})
arr.forEach(function(val,index,arr){
console.log( this,val,index,arr) // 此时this指向 123
},123)
注意:如果使用箭头函数作为回调函数,那么不管第二个参数传什么,this永远指向定义箭头函数所在的对象
arr.forEach((val,index,arr)=>{
console.log( this,val,index,arr) // 此时this指向 window
},123)
arr.includes( function( val ){ } ) // 包含 ,返回true、false
let arr = [1,2,3,4,5,6]
let arr2 = arr.indexOf(5) // 返回的是下标,没有找到就返回 -1 ES5 方法
let arr2 = arr.includes(5) // 返回的是布尔值,true
console.log(arr2) // true
arr.find( function( val, index, arr ){ } ) // 从左往右,找出第一个符合条件的数组成员,并返回出来(找成员)
arr.findIndex( function( val, index, arr ){ } ) // 从左往右,找出第一个符合条件的数组成员,并返回出来成员的索引,没找到则返回 -1(找位置)
let arr = [20,30,40,50]
let arr2 = arr.find((val,index,arr)=>{
return val>30
})
console.log(arr2) // 40
--------------------------------------------------
let arr = [20,30,40,50]
let arr2 = arr.findIndex((val,index,arr)=>{
return val>30
})
console.log(arr2) // 2
arr.fill( function( 填充的内容, 开始位置, 结束位置(不包含) ){ } ) // 填充或覆盖
空数,组填充
let arr = []
arr.length = 6
let arr2 = arr.fill("默认值")
console.log(arr2) // ["默认值", "默认值", "默认值", "默认值", "默认值", "默认值"]
-------------------------------------------------------------------------------------
实体数组,覆盖
let arr = [20,30,40,50]
let arr2 = arr.fill("默认值")
console.log(arr2) // ["默认值", "默认值", "默认值", "默认值"]
-------------------------------------------------------------------------------------
let arr = [1,2,3,4,5,6]
let arr2 = arr.fill("默认值",2,5)
console.log(arr2) // [1, 2, "默认值", "默认值", "默认值", 6]
arr.reduce(function(prev,val,index,arr){ }) // 从左往右计算 数组求和、阶乘等 用法如下
arr.reduceRight(function(prev,val,index,arr){ }) // 从右往左计算 数组求和、阶乘等 用法如下
数组求和
let arr = [1,2,3,4,5,6,7,8,9,10]
let arr1 = arr.reduce( function(prev,val, index, arr ){
return prev + val // 前面数字的和 + 当前的数
})
prev:指前面的元素的和
console.log(arr1) // 55
let arr = [1,2,3,4,5,6,7,8,9,10]
let arr1 = arr.reduceRight( function(prev,val, index, arr ){
return prev + val // 前面数字的和 + 当前的数
})
prev:指前面的元素的和
console.log(arr1) // 55
ES2017 新增了一个运算符,幂运算符:**
let str = Math.pow(2,3) // 2的3次方 以前的算法
let str = 2**3 // 2的3次方 新增的运算符
console.log(str)
for of 循环:for of 可以循环很多东西,这里介绍数组的循环
let arr = ["red","blue","green"]
for(let val of arr){ // 循环元素
console.log(val) // red blue green
}
for(let index of arr.keys()){ // 循环索引
console.log(index) // 0 1 2
}
for(let item of arr.entries()){ // 循环实体
console.log(item) // [0, "red"] [1, "blue"] [2, "green"]
}
for(let [key,val] of arr.entries()){ // 循环索引,和元素
console.log(key,val) // 0 "red" 1 "blue" 2 "green"
}
由此可以看出数组新增了两个方法:arr.keys() 数组下标 arr.entries() 数组某一项
2.数组新增
Array.from( arr ) 伪(类)数组转数组。arr 一定要有length属性 否则 Array.from 失效
<html lang="en">
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</html>
<script>
//伪(类)数组一般是一组dom节点,或者是函数的auguments的对象
let aLi = document.querySelectorAll("li")
let arrLi = [].slice.call(aLi) // 方法1 ES5 的方法
let arrLi = [...aLi] // 方法2 扩展运算符
let arrLi = Array.from(aLi) // 方法3 ES6新增
</script>
length问题:
let str = 'asdf'
let arr = Array.from(str)
console.log(arr) // ["a", "s", "d", "f"]
--------------------------------------------------------------------------------------------
let json = {
0:"a",
1:"b",
2:"c"
}
let arr1 = Array.from(json)
console.log(arr1) // [] json 没有呢length属性,Array.from失效,返回空数组
--------------------------------------------------------------------------------------------
let json1 = {
0:"a",
1:"b",
2:"c",
length:3
}
let arr2 = Array.from(json1)
console.log(arr2) // ["a", "b", "c"] json1 增加了length属性,Array.from成功
Array.of( arr ) 把一组值转成数组
let arr = Array.of("red","blue","green")
console.log(arr) // ["red", "blue", "green"]
3.常见数组使用方法
(1)两个数组的交集,并集,补集,差集
交集
const arr1 = [1,2,3,4],
arr2 = [2,4,6,8],
_arr1Set = new Set(arr1),
_arr2Set = new Set(arr2);
//es5
const arr = arr1.filter(function (val) {
return arr2.indexOf(val) > -1
})
//es6
const arr = arr1.filter(item => _arr2Set.has(item))
console.log(arr) // [2,4]
并集
const arr1 = [1,2,3,4],
arr2 = [2,4,6,8],
_arr1Set = new Set(arr1),
_arr2Set = new Set(arr2);
// es5
const arr = arr1.concat(arr2.filter(function (val) {
return !(arr1.indexOf(val) > -1)
}))
//es6
const arr = Array.from(new Set([...arr1, ...arr2]))
console.log(arr) // [1,2,3,4,6,8]
补集
const arr1 = [1,2,3,4],
arr2 = [2,4,6,8],
_arr1Set = new Set(arr1),
_arr2Set = new Set(arr2);
// es5
补集 两个数组各自没有的集合
const arr = arr1.filter(function (val) {
return !(arr2.indexOf(val) > -1)
}).concat(arr2.filter(function (val) {
return !(arr1.indexOf(val) > -1)
}))
//es6
const arr = [...arr1.filter(item => !_arr2Set.has(item)), ...arr2.filter(item => !_arr1Set.has(item))]
console.log(arr) // [1,3,6,8]
差集
const arr1 = [1,2,3,4],
arr2 = [2,4,6,8],
_arr1Set = new Set(arr1),
_arr2Set = new Set(arr2);
// 差集 数组arr1相对于arr2所没有的
// es5
const arr = arr1.filter(function (val) {
return arr2.indexOf(val) === -1
})
//es6
const arr = arr1.filter(item => !_arr2Set.has(item))
console.log(arr) // [1,3]
(2)数组去重,获取重复元素
去重
const arr = [1,0,0,2,9,8,3,1];
1.利用ES6中的 Set 方法去重
function unique(arr) {
return Array.from(new Set(arr))
}
console.log(unique(arr)); // [1,0,2,9,8,3]
or
console.log(...new Set(arr)); // [1,0,2,9,8,3]
2,使用双重for循环,再利用数组的splice方法去重(ES5常用)
function unique(arr) {
for (var i = 0, len = arr.length; i < len; i++) {
for (var j = i + 1, len = arr.length; j < len; j++) {
if (arr[i] === arr[j]) {
arr.splice(j, 1);
j--; // 每删除一个数j的值就减1
len--; // j值减小时len也要相应减1(减少循环次数,节省性能)
// console.log(j,len)
}
}
}
return arr;
}
console.log(unique(arr)); // [1,0,2,9,8,3]
3,利用数组的indexOf方法去重
function unique(arr) {
var arr1 = []; // 新建一个数组来存放arr中的值
for (var i = 0, len = arr.length; i < len; i++) {
if (arr1.indexOf(arr[i]) === -1) {
arr1.push(arr[i]);
}
}
return arr1;
}
console.log(unique(arr)); // [1,0,2,9,8,3]
4,利用数组的sort方法去重(相邻元素对比法)
function unique(arr) {
arr = arr.sort();
var arr1 = [arr[0]];
for (var i = 1, len = arr.length; i < len; i++) {
if (arr[i] !== arr[i - 1]) {
arr1.push(arr[i]);
}
}
return arr1;
}
console.log(unique(arr)); // [1,0,2,9,8,3]
5,利用数组的includes去重
function unique(arr) {
var arr1 = [];
for (var i = 0, len = arr.length; i < len; i++) {
if (!arr1.includes(arr[i])) {
// 检索arr1中是否含有arr中的值
arr1.push(arr[i]);
}
}
return arr1;
}
console.log(unique(arr));// [1,0,2,9,8,3]
6,利用数组的filter方法去重
function unique(arr) {
// 如果新数组的当前元素的索引值 == 该元素在原始数组中的第一个索引,则返回当前元素
return arr.filter(function(item, index) {
return arr.indexOf(item, 0) === index;
});
}
console.log(unique(arr)); // [1,0,2,9,8,3]
7,利用函数递归去重
function unique(arr) {
var arr1 = arr;
var len = arr1.length;
arr1.sort((a, b) => {
return a - b;
});
function loop(index) {
if (index >= 1) {
if (arr1[index] === arr1[index - 1]) {
arr1.splice(index, 1);
}
loop(index - 1); // 递归loop,然后数组去重
}
}
loop(len - 1);
return arr1;
}
console.log(unique(arr)); // [1,0,2,9,8,3]
8,利用ES6中的Map方法去重
let arr = [1, 0, 8, 3, -9, 1, 0, -9, 7];
function unique(arr) {
let map = new Map();
console.log(map);
//let arr1 = new Array(); // 数组用于返回结果
let arr1 = [];
for (let i = 0, len = arr.length; i < len; i++) {
if (map.has(arr[i])) {
// 判断是否存在该key值
map.set(arr[i], true);
} else {
map.set(arr[i], false);
arr1.push(arr[i]);
}
}
return arr1;
}
console.log(unique(arr)); // [1,0,2,9,8,3]
获取数组重复元素
function refrain(arr) {
var tmp = [];
if(Array.isArray(arr)) {
arr.concat().sort().sort(function(a,b) {
if(a==b && tmp.indexOf(a) === -1) tmp.push(a);
});
}
return tmp;
}
//for循环indexof()
function refrain(arr) {
var tmp = [];
for (var i =0; i <arr.length; i++) {
if(tmp.indexOf(arr[i])==-1 && arr.indexOf(arr[i])!==arr.lastIndexOf(arr[i])){
tmp.push(arr[i]);
}
}
return tmp;
}
获取数组每个元素重复次数
var arr=['a','a','a','b','C','d','d',2,2,2];
function refrainNum(arr){
var arr1= [];
for(var i=0;i<arr.length;i++){
var tmp=arr[i];
var n=0; //重复个数
for(var j=0;j<arr.length;j++){
if(arr[j]==tmp){
n++;
arr[j]=-1;
}
}
if(tmp != -1){
arr1.push(tmp + "=>" + n + "次");
}
}
return arr1;
}
console.log(refrainNum(arr)); // ["a=>3次", "b=>1次", "C=>1次", "d=>2次", "2=>3次"]