js---数组方法

357 阅读6分钟

变异方法(原数组会改变)

1. push() 、 pop()、 shift() 、 unshift(), 原数组会改变, 返回值为操作后新数组的length
let arr = [1,2,3,4];
//push
let push_arr =  arr.push('hellow');
console.log(arr); // [1, 2, 3, 4, 'hellow'];
console.log(push_arr); // 5
2. sort() 排序,原数组会改变, 返回值为操作后新数组
let arr=[1,100,5,20];
function sortNumber(a,b){return a - b};
console.log(arr.sort(sortNumber)); // [1, 5, 20, 100]
console.log(arr); // [1, 5, 20, 100] (原数组改变)
3. reverse() 反转数组, 原数组会改变, 返回值为操作后新数组
let arr=[12,25,5,20];
console.log(arr.reverse()); // [20, 5, 25, 12]
console.log(arr); // [20, 5, 25, 12] (原数组改变)
4. splice() 增删改,原数组会改变,返回值为操作项组成的数组

arr.splice(index , howmany , item1,.....,itemX)

index:必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。

howmany:必需。要删除的项目数量。设置为 0,增加。设置为1或其他数字,则表示替换。

item1, ..., itemX:可选。向数组添加的新项目。

4.1 删除
let arr = ['哈哈',  '呜呜', '嘿嘿', '啦啦']
let newArr = arr.splice(1,1)
console.log(newArr)  // ['呜呜']
console.log(arr)  // ['哈哈', '嘿嘿', '啦啦']
4.2 替换
let arr = ['哈哈',  '呜呜', '嘿嘿', '啦啦']
let newArr = arr.splice(1,1,'new')
console.log(newArr) // ["呜呜"]
console.log(arr) // ["哈哈", "new", "嘿嘿", "啦啦"]
4.3 增加
let arr = ['哈哈',  '呜呜', '嘿嘿', '啦啦']
let newArr = arr.splice(1,0,'new')
console.log(newArr)  // []
console.log(arr)  // ["哈哈", "new", '呜呜', "嘿嘿", "啦啦"]

非变异方法(原数组一般情况下不会改变)

1. map 遍历/映射 原数组不会改变,返回值是return组成的新数组,没有return,那就映射成undefined返回
1.1 map一般用于处理原数组得到一个新数组
let arr = [{age:1,name:'张三'},{age:2,name:'李四'}]
let newArr = arr.map(x =>{if(x.age===2){return x.name}})
console.log(newArr) //[undefined, '李四']
1.2 map当然也可以直接处理原数组,这个时候作用类似forEach()
  //这个情况下不用新数组去接收了
  let arr = [{ age: 1, name: '张三' }, { age: 2, name: '李四' }, { age: 3, name: '王五' }]
  let newArr = arr.map(x => { if (x.age === 2) { x.name = "xxxxxx" } })
  console.log(arr) //[{ age: 1, name: '张三' }, { age: 2, name: 'xxxxxx' }, { age: 3, name: '王五' }]
  console.log(newArr) //[undefined, undefined, undefined]
1.3 map 和 forEach的弊端是无法使用break, continue等关键字,只能使用return,作用类似原生for循环的continue,意味着无法终止循环。要想找到某一条件项后终止整个循环还是得用原生for配合break遍历。
  // return后只是该项不会进行下面打印操作,但是数组还是接着遍历下一项
  let arr = [{ age: 1, name: '张三' }, { age: 2, name: '李四' }, { age: 3, name: '王五' }]
  let newArr = arr.map(x => {if (x.age === 2) { return; }
  console.log(x.name) })  //张三  王五
2. forEach() 遍历 返回值为undefined,常用于遍历操作原数组
let arr = [{age:1,name:'张三'},{age:2,name:'李四'}]
let newArr = arr.forEach(x => {x.sex='男'})
console.log(newArr) // undefined
console.log(arr) // [{age:1, name:'张三', sex:'男'},{age:2, name:'李四', sex:'男'}]
3. join() (数组转字符串)常和split() 配合实现字符串的部分替换,返回值为字符串,原数组不变,默认为逗号分隔符
let arr = [1,2,3,4];
console.log(arr.join("-")); // 1-2-3-4
4. concat() 连接多个数组,返回值为连接后的数组,原数组不变
let arr1 = [1,2,3,4];
let arr2 = [5] 
let arr3 = [6]
console.log(arr1.concat(arr2, arr3)) // [1, 2, 3, 4, 5, 6]
5. slice()截取。原数组不变,返回值为截取的数组

arr.slice(startIndex , endIndex); startIndex为负数时,表示从尾部开始截取 endIndex 可选参数,为结束的索引,注意不包含此项,没有表示截取到最后一项 当 startIndex , endIndex都没提供时,表示截取整个数组,此时是拷贝数组常用的一种方法。注意当没对数组里面的值若是引用类型时,该拷贝也是浅拷贝。

let arr = [1, 2, 3, 4]
console.log(arr.slice(1,2))  // [2]
let arr1 = [1, 2, 3, 4]
let arr2 = arr1.slice( )
console.log(arr2)  // [1, 2, 3, 4]
arr1[0] = 99
console.log(arr2)  //  [1, 2, 3, 4]   数组的值为基本类型时是深拷贝

 let arr3 = [{ name: "bwf" }, { name: "wmy" },];
 let arr4 = arr3.slice();
 arr3[0].name = "xxxx";
 console.log(arr4) //[{ name: "xxxx" }, { name: "wmy" },]数组的值为引用类型时是浅拷贝

6. indexOf()和 lastIndexOf() 返回检测到该项的索引,数组中若没有该项,则返回-1,常用于检查一维数组中是否含有某项,无法直接检查[{name: 'zs'}, {name:'ls'}]这样的数组
let arr = [1, 2, 3, 4]
console.log(arr.indexOf(2)) // 1
console.log(arr.indexOf(5)) // -1
7. filter() 过滤,返回值是 return为true的组装到一个新数组。原数组不变。
 let arr = [1,2,3,4];
 let result = arr.filter((item) => {
        return item > 3;
    });
console.log(result) // [4]
8. some()、every() 检测符合条件的,返回值为布尔值,原数组不变。

some() return中有一项为true, 结果为true,而且后面项不再进行遍历; every() return所有项为true,结果才为true。若有一项为false,立即返回false.后面的项不再进行遍历。

 let arr = [1,2,3,4];
 let resultSome = arr.some((item) => {
        return item > 3;
    });
 let resultEvery = arr.every((item) => {
        return item > 3;
    });
console.log(resultSome) // true
console.log(resultEvery) // false
9. find() findIndex ()查找,原数组不变。

find()返回符合条件的项,没有符合条件的项则返回 undefined。匹配到了后面的就不再遍历了。 findIndex ()返回符合项的索引,没有符合的则返回-1

let arr = [1,2,3,4];
let resultFind = arr.find((item) => {
       return item > 2;
   });
console.log(resultFind) // 3
10. Array.from()将伪数组(有length属性但没有数组方法的对象)转化成真正的数组,常配合new Set() 等使用。原数组不变,返回值为新数组。
let obj ={
	    'name':'哈哈',
	    'age':'13',
	    '0':'张三',
	    length:3
	}
let arr = Array.from(obj);
console.log(arr)  // ["张三", undefined, undefined]
11. reduce() 数组的归并方法,除遍历外可同时将前面数组项遍历产生的结果与当前遍历项进行运算

arr.reduce(function(prev,cur,index,arr){ }, init); prev: 表示上一次调用回调时的返回值,或者初始值 init 或者 数组第一项; cur: 表示当前正在处理的数组元素; index: 表示当前正在处理的数组元素的索引; init: 表示初始值可以为空数组 空对象等。

 //求和
  let arr = [3, 9, 4, 3, 6, 0, 9];
  let sum = arr.reduce((prev, cur, index) => prev + cur, 0)
  console.log(sum);
  
//求最大值
  let max = arr.reduce((prev, cur, index) =>
    Math.max(prev, cur)
  )
  console.log(max);
 
//去重
  let newArr = arr.reduce((prev, cur, index) => {
    prev.indexOf(cur) === -1 && prev.push(cur)
    return prev
  }, [])
  console.log(newArr);
  
// 重组
  let arr2 = [
    { name: "王1", age: 16 },
    { name: "李2", age: 20 },
    { name: "张3", age: 30 },
  ]
  let arr3 = ["userWang", "userLi", "userZhang"]
  let userObj = arr2.reduce((prev, cur, index) => {
    prev[arr3[index]] = cur;
    return prev;
  }, {}) 
  console.log(userObj); // {userLi: {name: "李2", age: 20}, userWang: { name: "王1", age: 16 }, userZhang: { name: "张3", age: 30 } }
12. for...of for...in
  • for...of循环可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)、后文的 Generator 对象,以及字符串。
  • for...in 既可以直接遍历普通对象,又可以遍历数组;而for...of只能直接遍历的是部署了 Iterator 接口结构。
  • for...in循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键;而for...of不会。
  • for...of,内部可以与break、continue配合使用;但是forEach map内部只能放return关键字
// for...in  遍历默认拿到的键名
var arr = ['a', 'b', 'c', 'd'];
for (let a in arr) {
  console.log(a); // 0 1 2 3
}

// for...of  遍历默认拿到的键值
for (let a of arr) {
  console.log(a); // a b c d
}

// 对于普遍对象,直接遍历的话只能采用 for...in
let es6 = {
  edition: 6,
  committee: "TC39",
  standard: "ECMA-262"
};
for (let e in es6) {
  console.log(e);  //edition  committee  standard
}
for (let e of es6) {
  console.log(e);  // TypeError: es6[Symbol.iterator] is not a function
}
// for...in循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键
let arr = [11, 22, 33]
  Array.prototype.say = function () { }
  Object.prototype.hellow = function () { }
  arr.age = 90
  for (const key in arr) {
    console.log('for...in', key);   // '0' '1' '2' age say hellow
  }
  for (const item of arr) {
    console.log('for...of', item); // 11 22 33
  }