JavaScript对数组的操作


本篇文章纯属于个人的学习总结,如果文章中出现错误或不严谨的地方,希望大家能够指出,谢谢!

数组检测的方法

  • instanceof
    主要是检测变量的原型链是否指向Array构造函数的prototype原型上,但instanceof不能保证返回的结果一定正确,因为只要在原型链上都会返回true。arr instanceof Object 也会返回true。
let arr = [1, 2, 3];
arr instanceof Array; //true
  • contructor
var arr = [];
arr.constructor === Array  return true
但constructor可以被重写,不能保证一定是数组
    var str = "abc";
    str.constructor = Array;
    str.constructor === Array //return true
很显然,str不是数组
  • Array.isArray()

ES5在Array上新增了检测数组的方法,存在兼容性问题。

  • Object.prototype.toString.call()

可以确保方法能检测一定是数组。

var arr = [1, 3, 6];
Object.prototype.toString.call(str) === "[object Array]"; //rturn true
  • 总结:

由于Array.isArray()是封装在浏览器中,运行效率比较高,所以当要真正检测变量类型时,先会检测浏览器是否支持Array.isArray(),之后再用Object.prototype.call()方法。代码应该如下:

// 判断元素是不是数组
    let arr4 = "12, 45";

    function isArray(value) {
      if (typeof Array.isArray === "function") {
        return Array.isArray(value);
      } else {
        return Object.prototype.toString.call(value) === "[object Array]";
      }
    }
    console.log(isArray(arr4));

数组对象方法

创建
let a = new Array(); 等价于 let a = [];
实例方法
  • push()

在数组最后添加,返回新数组的长度,改变原数组

  • pop()

删除数组最后一项,返回删除的元素,改变原数组

  • shift()

删除数组中第一个元素,返回删除的元素,改变原数组

  • unshift()

在数组最前面添加,返回新数组的长度,改变原数组

  • fill(val, start, end)

用一个固定的值替换数组中的元素,返回新数组,改变原数组

  • reverse()

前后调换元素位置,返回新数组,改变原数组

  • sort()

数组排序,返回新数组,改变原数组。sort()方法会调用数组每项的toString()方法,比较字符串进行排序。

  • splice()

用于数组的删除、插入、替换,会改变原数组
一个参数时,表示删除的开始位置;
两个参数时,第一个表示删除的开始位置(0),第二个表示删除的个数;
三个参数时,删除的开始位置、删除的个数、添加的元素

  • join()

将原数组转化成字符串,默认以空格分隔,返回替换后的值,不改变原数组

  • concat()

将两个数组连接,返回新数组,不改变原数组

  • slice(start, end)

从数组中返回指定的元素,返回新数组,不改变原数组

位置方法
  • indexOf()

匹配数组,第一个参数为要查询的值,第二个参数表示开始查询位置,没有返回-1。

  • lastIndexOf()

从后面往上找,参数同上,起始位置从正向开始数

  • includes()

判断数组是否包含某一元素,返回布尔值。
第一个参数,要查询的元素
第二个参数,查询的开始位置。负数,表示从右数过来第几个,但是不改变判断搜索的方向,搜索方向还是从左到右。

迭代方法
  • every()

数组元素全部满足添加返回true,否则返回false

let nums = [1, 2, 3, 4, 5, 4, 3, 2, 1];
let everyResults = nums.every((item, index,array) => {
  return (item > 0);
    });
  console.log(everyResults); //true
  • some()

只要有一项满足条件就返回true,否则返回false。

let numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
let someResult = numbers.some((item, index, array)=>{
  return (item > 3);
});
console.log(someResult);
  • find()

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

//返回符合测试条件的数组元素值,如果没有符合条件的则返回undefined。
// 获取数组中大于18第一个的元素
let arr2 = [15, 6.8, 49.5, 102];
function findResult(array, value) {
  return array.find(value => {
    return value > 18
  })
}
console.log(findResult(arr2, 18));
  • findIndex()

原理和 find() 相同,但返回的索引值

  • filter()

过滤。过滤的元素组成新数组,不改变原数组。

// 获取数组中大于18第一个的元素
let arr2 = [15, 6.8, 49.5, 102];
function findResult(array, value) {
  return array.find(value => {
    return value > 18
  })
}
console.log(findResult(arr2, 18));
  • forEach()

遍历数组中的每个元素,并为每个元素执行指定操作,不改变元素组

let nums = [1, 2, 3, 4, 5, 4, 3, 2, 1];
nums.forEach((item, index, array) => {
  console.log(item)
})
  • map()

对数组中的每一项执行一些操作,返回新数组,改变原数组。

let numbers = [1,2,3,4,5,4,3,2,1];
let mapResult = numbers.map(function(item, index, array) {
    return item + 1;
});
console.log(mapResult);//[2, 3, 4, 5, 6, 5, 4, 3, 2]
归并方法
  • reduce()

prev:前一个值; cur: 当前值; index: 项的索引; array: 数组对象 。将数组中的数相加,返回和,不改变原数组。

// reduce 统计同一元素出现的次数
    let arr6 = [1, 2, 3, 1, 2, 5, 4, 6, 7, 8, 9, 1, 3];
function countNum(array, item) {
  return arr6.reduce((total, cur) => {
    total += cur === item ? 1 : 0;
    return total;
  }, 0);
}
console.log(countNum(arr6, 1)); //3
  • reduceRtght()

方法的功能和 reduce() 功能是一样的,不同的是 reduceRight() 从数组的末尾向前将数组中的数组项做累加。

区分数组和对象
let a = [];
let b = {};
function isArray (value) {
  //小写的是返回的值的格式中默认的,大写的是对象的名字Array
  return Object.prototype.toString.apply(value) == "[object Array]";
};
console.log(isArray(a));//true
console.log(isArray(b));//false

清空数组方法

  • arr.length = 0;

修改数组本身,如果通过一个不同的变量访问他,会得到修改的数组。

  • arr = [];

创建一个新数组,并为其赋予一个变量的引用。任何其他引用不受影响,并指向原数组。

  • arr.splice(0, arr.length);

  • while (arr.pop()) {}

数组去重

  • 要求:将两个数组合并,并去除重复部分
let arr1 = [1, 2, 3, 4, 5, 6];
let arr2 = [1, 2, 3, 4, 8, 6];
  • Array.filter() + indexOf()

思路:将两个数组拼接,使用ES6中的方法Array.filter()遍历数组,并结合indexOf()排除重复项。

function distinct(item1, item2) {
  let arr = item1.concat(item2);
  return arr.filter((item, index) => {
    return arr.indexOf(item) === index;
  });
}
console.log(distinct(arr1, arr2));
  • 双重for循环

思路:外层for循环遍历元素,内层循环检查元素是否重复,如果元素重复可以使用push()也可以使用splice()

// 双重for循环
function distinct(item1, item2) {
  let arr = item1.concat(item2);
  console.log(arr);
  for (let i = 0; i <= arr.length; i++) {
    for (let j = i + 1; j <= arr.length; j++) {
      if (arr[i] == arr[j]) {
        arr.splice(j, 1);
        // splice 会改变数组长度,要将数组下标减一
        j--;
      }
    }
  }
  return arr;
}
console.log(distinct(arr1, arr2));
  • for...of + includes()

思路:双重for循环的升级。外层for…代替for循环,把内层循环替换为includes(). 先创建一个空数组,当includes()返回false时,就将该元素push到数组中。类式,可以用indexOf替换includes。

function distinct(item1, item2) {
  let arr = item1.concat(item2);
  console.log(arr);
  let newArr = [];
  for (const i of arr) {
    !newArr.includes(i) ? newArr.push(i) : "";
  }
  return newArr;
}
console.log(distinct(arr1, arr2));
  • Array.sort()

思路:先将数组进行排序,然后比较两个相邻元素是否相同,去除重复项。

function distinct(item1, item2) {
  let arr = item1.concat(item2);
  arr = arr.sort();
  for (let i = 0; i < arr.length; i++) {
      arr[i] === arr[i - 1] && arr.splice(i, 1);
  }
  return arr;
}
console.log(distinct(arr1, arr2));
  • new Set()

思路:利用Set 对象存储的值总是唯一的特性。

function distinct(item1, item2) {
  return Array.from(new Set([...item1, ...item2]));
}
console.log(distinct(arr1, arr2));
  • for…of + Object

思路:创建一个空对象,用for循环遍历,利用对象的属性不能重复的特点,校验元素是否重复。

function distinct(item1, item2) {
  let arr = item1.concat(item2);
  let newArr = [];
  let obj = {};
  for (let i of arr) {
    if (!obj[i]) {
      newArr.push(i);
      obj[i] = 1;
    }
  }
  return newArr;
}
console.log(distinct(arr1, arr2));

性能:6> 5> 4> 3> 1> 2
参考网站//www.greatytc.com/p/6300a031dba5

数组扁平化

什么是数组扁平化?

数组扁平化是指:将多维数组转换成一维数组,即将数组内部嵌套着其他数组的数组提炼成没有嵌套的一维数组。

如何实现数组扁平化?
  • Array.prototype.flat()

ES6提供的方法,用于数组扁平化,会返回一个新数组,不会改变元素组。

let arr = [1, [2, 3],4];
console.log(arr.flat());//[1,2,3,4]

flat()默认扁平一层嵌套,可以带一个整数参数便是扁平的层数;

let arr = [1, [[2,3],4]];
console.log(arr.flat(2));

无论嵌套多少层,可以通过传递Infinity作为参数转为一维数组。

  • 使用扩展运算符和concat()

可以使用扩展运算符展开数组,再用concat()可以合并数组,但操作做一次只能展开一层;

let array = [1, [[2, 3], 4]] 
function flatten(array) {
    return [].concat(...array)
}
console.log(flatten(array))
// 打印[1, [2, 3], 4]

要完全展开要对嵌套的数组进行遍历才能展开

let arr = [1, [2, 3], 4];
console.log(arr.flat());

function flatten(array) {
  // 先用some()检测数组中的元素是否是数组
  while (array.some(item => {
      return Object.prototype.toString.call(item) === "[object Array]"
    })) {
    array = [].concat(...array);
  }
  return array;
};
console.log(flatten(arr));
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。