专题:数组方法

创建

数组创建的方法

es5Array方法可以创建数组,但是参数只有一个时创建会存在歧义

  1. console.log(Array()); //[]
  2. console.log(Array(2)); //[empty × 2]
  3. console.log(Array(1, 2, 3)); //[1, 2, 3]

es6Array.of静态方法解决以上歧义

  1. console.log(Array.of()); //[]
  2. console.log(Array.of(2)); //[2]
  3. console.log(Array.of(1, 2, 3)); //[1, 2, 3]

长度

关于数组和字符串的长度:

操作数组的长度是可变的,而字符串长度是不变的

示例:

  1. //字符串push新增
  2. var str = 'hello';
  3. str.push('vue');
  4. console.log(str);
  5. //报错 str is not a function
  6. //强行调用字符串的push方法
  7. Array.prototype.push.call(str, 'vue');
  8. console.log(str);
  9. //报错 Cannot assign to read only property 'length' of object '[object String]'
  10. //如何实现字符串长度增加?利用字符串拼接
  11. str += 'vue';

转字符串

将数组转为字符串的方法有toString

  1. var arr = ['a', 'b', 'c'];
  2. var res = arr.toString();
  3. console.log(res);
  4. //a,b,c

toString方法也可以实现数组多维降维的操作:

  1. var arr = ['a', 'b', ['c', ['d', 'e']]];
  2. var res = arr.toString();
  3. console.log(res);
  4. //a,b,c,d,e

扁平化

除了用toString方法,join方法也同样可以实现数组扁平化操作,但是如果以某一个字符串的形式拼接时只会扁平化一层

  1. var arr = ['a', 'b', ['c', ['d', 'e']]];
  2. //以默认的形式拼接时
  3. var res = arr.join();
  4. console.log(res);
  5. //a,b,c,d,e
  6. //当以'-'的形式拼接时,只能扁平化一层
  7. var res1 = arr.join('-');
  8. console.log(res1);

最原始化的扁平化方式

  1. //要求:编写一个程序将数组扁平化并将扁平化后的数组去重,最终得到一个升序且不重复的一维数组
  2. var arr = [
  3. [1, 2, 2],
  4. [3, 4, 5, 5],
  5. [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10
  6. ];
  7. //分析
  8. //1.扁平化 多维数组 -> 一维数组
  9. //2.数组元素去重
  10. //3.数组元素升序
  11. //1.扁平化程序
  12. console.log(faltten(arr));
  13. //[1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]
  14. function faltten(arr) {
  15. //有传数组用有传数组,没有时用空数组
  16. var _arr = arr || [],
  17. // 新数组容器
  18. fArr = [],
  19. //保存并简写数组长度
  20. len = _arr.length,
  21. item;
  22. for (var i = 0; i < len; i++) {
  23. //数组元素
  24. item = _arr[i];
  25. //1.检测一维数组的数组元素是否为数组
  26. function _isArr(item) {
  27. //证明为数组元素是数组
  28. return {}.toString.call(item) === '[object Array]';
  29. }
  30. //2.如果是数组,需要用到递归再次扁平化数组
  31. if (_isArr(item)) {
  32. //把扁平化的单一数组拼接为一个整合数组
  33. fArr = fArr.concat(faltten(item));
  34. } else {
  35. //如果单一项不是数组,把该项push进数组
  36. fArr.push(item);
  37. }
  38. }
  39. return fArr;
  40. }

原始方法的健全写法

  1. //原始方法的健全写法
  2. Array.prototype.faltten = function () {
  3. //好习惯:保存this,谁调用执行谁
  4. var _arr = this,
  5. toStr = {}.toString,
  6. fArr = [];
  7. if (toStr.call(_arr) !== '[object Array]') {
  8. throw new Error('只有数组才能调用flatten方法');
  9. }
  10. // 写法一:forEach
  11. _arr.forEach(function (item) {
  12. toStr.call(item) === '[object Array]' ?
  13. fArr = fArr.concat(item.faltten()) :
  14. fArr.push(item);
  15. });
  16. return fArr;
  17. //写法二:reduce 归纳
  18. return _arr.reduce(function (prev, item) {
  19. return prev.concat(toStr.call(item) === '[object Array]' ?
  20. item.faltten() :
  21. item);
  22. }, []);
  23. }
  24. //faltten方法调用
  25. console.log(arr.faltten());
  26. //[1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]

es6原始写法

  1. //es6简写:
  2. const flatten = arr => arr.reduce((prev, item) =>
  3. prev.concat({}.toString.call(item) === '[object Array]' ? flatten(item) : item), []);
  4. //标准写法
  5. const flatten = (arr) => {
  6. return arr.reduce((prev, item) => {
  7. return prev.concat({}.toString.call(item) === '[object Array]' ? flatten(item) : item)
  8. }, [])
  9. }
  10. //flatten方法调用
  11. console.log(flatten(arr));
  12. //[1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]

去重

  1. //写法一:
  2. // 最先想到的办法: for循环
  3. function uniqueArr(array) {
  4. //数组容器
  5. var _arr = [],
  6. isReapeat;
  7. for (var i = 0; i < array.length; i++) {
  8. //默认为false
  9. isReapeat = false;
  10. //遍历数组容器
  11. for (var j = 0; j < _arr.length; j++) {
  12. //证明重复了
  13. if (_arr[j] == array[i]) {
  14. //并定义为true
  15. isReapeat = true;
  16. //不能往_arr容器里增加元素
  17. break;
  18. }
  19. }
  20. //这里外层for循环仍会继续循环
  21. //如需终止循环,声明变量isReapeat枷锁
  22. if (!isReapeat) {
  23. //在循环外push元素
  24. _arr.push(array[i]);
  25. }
  26. }
  27. return _arr;
  28. }
  29. console.log(uniqueArr(arr).sort());;
  30. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  1. //写法二: 当前项对比下一项,如不重复push进去
  2. //效率较慢
  3. function uniqueArr(array) {
  4. var _arr = [],
  5. isReapeat;
  6. for (var i = 0; i < array.length; i++) {
  7. isReapeat = false;
  8. for (var j = i + 1; j < array.length; j++) {
  9. if (array[i] == array[j]) {
  10. isReapeat = true;
  11. break;
  12. }
  13. }
  14. if (!isReapeat) {
  15. _arr.push(array[i]);
  16. }
  17. }
  18. return _arr;
  19. }
  20. console.log(uniqueArr(arr).sort());;
  21. //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  1. //写法三
  2. //filter
  3. function uniqueArr(array) {
  4. return array.filter(function (item, index) {
  5. //相等代表不重复
  6. //filter返回新数组
  7. //indexOf(item)只返回一次元素下标,无论元素重复多少个
  8. return array.indexOf(item) === index;
  9. // return array.indexOf(item);
  10. //[2, 6, 3, 5, 0, 3, 6, 8, 9, 4, 4, 2, 0, 9, 5, 2, 7, 4, 2, 3, 4, 6]
  11. // return index;
  12. //[1, 2, 6, 3, 5, 0, 3, 6, 8, 9, 4, 4, 2, 0, 9, 5, 2, 7, 4, 2, 3, 4, 6]
  13. //return array.indexOf(item) === index;
  14. //[1, 2, 6, 3, 5, 0, 8, 9, 4, 7]
  15. })
  16. }
  17. console.log(uniqueArr(arr).sort());
  1. //写法四
  2. //利用forEach
  3. function uniqueArr(array) {
  4. var _arr = [];
  5. array.forEach(function (item) {
  6. if (_arr.indexOf(item) === -1) {
  7. _arr.push(item);
  8. }
  9. })
  10. return _arr;
  11. }
  12. console.log(uniqueArr(arr));
  13. //[1, 2, 6, 3, 5, 0, 8, 9, 4, 7]
  1. //写法五
  2. //利用sort
  3. function uniqueArr(array) {
  4. var _arr = [];
  5. //先排序后循环
  6. //此操作会把相同的项排序在一起
  7. array.sort();
  8. // console.log(array);
  9. //[0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 7, 8, 9, 9]
  10. for (var i = 0; i < array.length; i++){
  11. // 利用sort写法一
  12. //如当前项跟下一项不相等
  13. if (array[i] !== array[i + 1]) {
  14. _arr.push(array[i]);
  15. }
  16. // 利用sort写法二
  17. //原理:找最后一项对比
  18. if (array[i] !== _arr[_arr.length - 1]) {
  19. _arr.push(array[i]);
  20. }
  21. }
  22. return _arr;
  23. }
  24. console.log(uniqueArr(arr));
  25. //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  1. //写法六
  2. //es6 - include()
  3. function uniqueArr(array) {
  4. var _arr = [];
  5. array.forEach(function (item) {
  6. if (!_arr.includes(item)) {
  7. _arr.push(item);
  8. }
  9. });
  10. return _arr;
  11. }
  12. console.log(uniqueArr(arr).sort());
  13. //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

indexOf()include()区别:

  • indexOf: 返回-1/index 可返回具体位置,对NaN无效
  • include:返回true/false 不可返回具体位置,对NaN有效
  1. //写法七
  2. //reduce sort
  3. function uniqueArr(array) {
  4. var _arr = [],
  5. //Set数据结构里面的值是唯一的
  6. _temp = new Map();
  7. for (var i = 0; i < array.length; i++) {
  8. //如果拿不到数组该元素
  9. if (!_temp.get(array[i])) {
  10. //map里面没有该属性,应往里添加属性
  11. //myMap.set(元素的键, 元素的值);返回值 Map 对象
  12. // console.log(array[i]);
  13. //{array[i] => 1}
  14. _temp.set(array[i], 1);
  15. //把键名push到数组里
  16. // console.log(array[i]);
  17. _arr.push(array[i]);
  18. }
  19. }
  20. return _arr;
  21. }
  22. console.log(uniqueArr(arr).sort());
  23. //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  1. //写法八
  2. //Array.from()
  3. function uniqueArr(array) {
  4. //将类数组(对象)转为数组
  5. return Array.from(new Set(array));
  6. }
  7. console.log(uniqueArr(arr).sort());

转类数组

es6中的Array.from静态方法可以将类数组转为数组,和es5中的Array.prototype.slice.call()方法实现一致

  1. function test(a, b) {
  2. console.log(Array.from(arguments));
  3. //[1, 2]
  4. }
  5. test(1, 2);
  6. var str = 'hello';
  7. console.log(Array.from(str));
  8. //['h', 'e', 'l', 'l', 'o']

元素增删查

堆栈

push,unshift方法的返回值均为数组的长度

  1. var arr = ['a', 'b', 'c'];
  2. var res1 = arr.push('d');
  3. console.log(arr, res1);
  4. //['a', 'b', 'c', 'd'] 4
  5. var res2 = arr.unshift('0');
  6. console.log(arr, res2);
  7. //['0', 'a', 'b', 'c', 'd'] 5

popunshift方法的返回值是删除的该项元素

  1. var res3 = arr.pop();
  2. console.log(arr, res3);
  3. //['0', 'a', 'b', 'c'] 'd'
  4. var res4 = arr.shift();
  5. console.log(arr, res4);
  6. //['a', 'b', 'c'] '0'

截取

splice方法可以对数组元素进行截取,会操作原数组

  1. var arr1 = ['a', 'b', 'c'];
  2. var arr2 = ['a', 'b', 'c', 'd'];
  3. var arr3 = ['a', 'b', 'c', 'd'];
  4. var arr4 = ['a', 'b', 'c', 'd'];
  5. var arr5 = ['a', 'b', 'c', 'd'];
  6. var arr6 = ['a', 'b', 'c', 'd'];
  7. //只有一个参数时,返回删除元素组成的数组,没有时为空数组
  8. var res1 = arr1.splice();
  9. console.log(arr1, res1);
  10. //['a', 'b', 'c'] []
  11. var res2 = arr2.splice(2);
  12. console.log(arr2, res2);
  13. //['a', 'b'] ['c', 'd']
  14. //两个参数时,返回删除元素组成的数组
  15. //参数1:起始增加或删除的位置
  16. //参数2:截取长度
  17. var res3 = arr3.splice(0, 2);
  18. console.log(arr3, res3);
  19. //['c', 'd'] ['a', 'b']
  20. var res4 = arr4.splice(0, 3);
  21. console.log(arr4, res4);
  22. //['d'] ['a', 'b', 'c']
  23. //三个参数时,返回删除元素组成的数组,修改指定位置为指定元素
  24. var res5 = arr5.splice(0, 1, 'hello');
  25. console.log(arr5, res5);
  26. //['hello', 'b', 'c', 'd'] ['a']
  27. //第二参数为undefined/-1/NaN/null,不会发生截取内容时,返回空数组
  28. var res6 = arr6.splice(0, null);
  29. console.log(arr6, res6);
  30. //['a', 'b', 'c', 'd'] []

slice方法可以对数组元素进行截取,返回新的数组

  1. var arr = ['a', 'b', 'c'];
  2. //slice返回截取内容,第一位到最后
  3. //[) 左闭右开 左包含右不包含
  4. var res1 = arr.slice(1);
  5. console.log(arr, res1);
  6. //['a', 'b', 'c'] ['b', 'c']
  7. var res2 = arr.slice(1, 2);
  8. console.log(arr, res2);
  9. //['a', 'b', 'c'] ['b']

slice方法也可以将字符串转为数组

  1. var str = 'hello';
  2. var arr = Array.prototype.slice.call(str);
  3. console.log(str, arr);
  4. //hello ['h', 'e', 'l', 'l', 'o']

slice方法也可以将类数组转为数组

  1. function test(a, b) {
  2. console.log(arguments);
  3. //Arguments(2) [1, 2, callee: ƒ, Symbol(Symbol.iterator): ƒ]
  4. var arr = Array.prototype.slice.call(arguments);
  5. console.log(arr);
  6. //[1, 2]
  7. }
  8. test(1, 2);

排序

正序

  1. //sort方法操作的是原数组
  2. var arr = [1, 2, 3];
  3. var res = arr.sort((a, b) => a - b);
  4. console.log(arr, res);
  5. //[1, 2, 3] [1, 2, 3]

倒序

  1. var arr = [1, 2, 3];
  2. var arr2 = [4, 5, 6];
  3. //reverse方法操作的是原数组
  4. var res1 = arr.reverse();
  5. console.log(arr, res1);
  6. //[3, 2, 1] [3, 2, 1]
  7. //sort
  8. var res2 = arr2.sort((a, b) => b - a);
  9. console.log(arr2, res2);
  10. //[6, 5, 4] [6, 5, 4]

乱序

  1. var arr = [1, 2, 3];
  2. var res = arr.sort(() => {
  3. var ran = Math.random();
  4. // console.log(ran);
  5. //0.1 - 0.9
  6. return ran - 0.5;
  7. });
  8. console.log(arr, res);
  9. //[1, 3, 2] [1, 3, 2]

拼接

concat方法操作返回的是新的数组,并且只能拼接多维数组中的第一层,多层降维时需要递归拼接

  1. var arr = [1, 2, 3];
  2. var res1 = arr.concat(4);
  3. console.log(arr, res1);
  4. //[1, 2, 3] [1, 2, 3, 4]
  5. var res2 = arr.concat(4, [5, 6]);
  6. console.log(arr, res2);
  7. //[1, 2, 3] [1, 2, 3, 4, 5, 6]
  8. var res3 = arr.concat(4, [5, [6, 7]]);
  9. console.log(arr, res3);
  10. //[1, 2, 3] [1, 2, 3, 4, 5, Array(2)]

es6拓展运算符的方法进行拼接,不能降维操作

  1. var arr = [1, 2, 3];
  2. var res1 = [...arr, 4];
  3. console.log(arr, res1);
  4. //[1, 2, 3] [1, 2, 3, 4]
  5. var res2 = [...arr, 4, [5, 6]];
  6. console.log(arr, res2);
  7. //[1, 2, 3] [1, 2, 3, 4, Array(2)]
  8. var res3 = [...arr, 4, [5, [6, 7]]];
  9. console.log(arr, res3);
  10. //[1, 2, 3] [1, 2, 3, 4, Array(2)]

索引

indexOflastIndexOf是查找索引的方法,区别在从前面或后面顺序开始查找

  1. //返回查找元素的索引
  2. var arr = ['a', 'b', 'c'];
  3. console.log(arr.indexOf('a')); //0
  4. console.log(arr.indexOf('c')); //2
  5. console.log(arr.lastIndexOf('a')); //0
  6. console.log(arr.lastIndexOf('c')); //2

包含

includes方法查找数组是否包含指定元素,返回布尔值

  1. var arr = ['a', 'b', 'c'];
  2. console.log(arr.includes('a')); //true
  3. console.log(arr.includes('d')); //false

查找

es6find方法返回第一个符合条件的数组元素,参数是一个定义条件的函数

  1. var arr = [1, 2, 3, 4, 5];
  2. console.log(arr.find((n) => n > 2)); //3

es6findIndex方法返回第一个符合条件的数组元素的索引,参数是一个定义条件的函数

  1. var arr = [1, 2, 3, 4, 5];
  2. console.log(arr.findIndex((n) => n > 2)); //2

填充

fill方法将数组内所有的元素填充为指定的值

  1. var arr1 = ['a', 'b', 'c'];
  2. var arr2 = ['a', 'b', 'c'];
  3. var res1 = arr1.fill('d');
  4. console.log(arr1, res1);
  5. //['d', 'd', 'd'] ['d', 'd', 'd']
  6. //参数1为填充的值, 参数2和3是选定的区间 左闭右开
  7. var res2 = arr2.fill('d', 0, 1);
  8. console.log(arr2, res2);
  9. //['d', 'b', 'c'] ['d', 'b', 'c']

元素遍历

关于遍历键名/键值/键值对:

keysvaluesentries方法返回的是一个有序数组可迭代对象,需要for..of遍历获取键名或键值或键值对

  1. var arr = ['a', 'b', 'c'];
  2. for (var key of arr.keys()) {
  3. console.log(key); //0 1 2
  4. }
  5. for (var value of arr.values()) {
  6. console.log(value); //a b c
  7. }
  8. for (var [key, value] of arr.entries()) {
  9. console.log(key, value); //0 'a' 1 'b' 2 'c'
  10. }

forEach

forEach循环每一项数组元素,返回值为undefined,函数内部this指向window,第二参数可以改变this指向(回调函数箭头写法失效)

  1. var arr = ['a', 'b', 'c'];
  2. console.log(arr.forEach(function(item){ console.log(this); //window })); //undefined

forEachfor循环的区别:

  • forEach遇到数组长度为0时forEach的内部函数并不会执行遍历
  • forEach遇到稀疏数组时,空缺的元素并不会执行遍历
  • forEach不可以breakcontinue中止或跳出循环
  • forEach不可以遍历对象,可以[].forEach.call()遍历
  • for遇到数组长度为0时不会执行循环
  • for遇到稀疏数组时,会循环,缺失的元素会打印undefined
  • for可以breakcontinue中止或跳出循环

map

根据原数组能够返回一个和原数组产生映射关系的数组

  1. console.log([1, 2, 3].map((item) => item * 2));
  2. //[2, 4, 6]

filter

返回过滤后的数组元素组合的数组,函数内部必须返回布尔值,布尔值决定了当前过滤的方式,true留下,false过滤

  1. console.log([1, 2, 3, 4].filter((item) => (item > 2 ? true : false)));
  2. //[3, 4]

some

返回布尔值,如果某一项数组元素符合条件返回true

  1. console.log([1, 2, 3].some((item) => item === 2));
  2. //true

every

返回布尔值,如果所有项数组元素符合条件返回true

  1. console.log([1, 2, 3].every((item) => item > 0));
  2. //true
  3. console.log([1, 2, 3].every((item) => item > 1));
  4. //false

reduce

归纳函数,迭代器,累加器,当考虑想获取具体格式的值或数据格式时,可以考虑使用reduce