Bootstrap

30个数组方法/数组去重/数组置空/数组方法是否影响原数组

Array.length

Array.length方法用于检测数组长度或将数组置空

    let arr = ['a','b','c']
    console.log(arr.length)// 3
    arr.length = 0
    console.log(arr)// []

Array.from()

Array.from()用于将伪数组或可迭代对象(包括arguments Array,Map,Set,String…)转换成数组对象
语法:Array.from(arrayLike, mapFn, thisArg)

返回值:一个新的数组实例

参数说明:

arrayLikemapFn (可选参数)thisArg(可选参数)
想要转换成数组的伪数组对象或可迭代对象一个map方法,如果指定了该参数,新数组中的每个元素会执行该回调函数执行回调函数 mapFn 时 this 对象,map方法里面的this指向
 

// 将字符串转换为数组:  
let str = 'foo'
console.log(Array.from(str)) // ['f', 'o', 'o']


// 将对象转换为数组的条件比对:
let info1 = {
    0: 'tom',
    1: '65',
    2: '男',
    3: ['jane', 'john', 'Mary'],
    'length': 4
  }
  console.log(Array.from(info1)) // ['tom', '65', '男', Array(3)]
let info2 = {
    'name': 'tom',
    'age': '65',
    'sex': '男',
    'friends': ['jane', 'john', 'Mary'],
    length: 4
  }
  console.log(Array.from(info2)) // [undefined, undefined, undefined, undefined]


// 将Set结构的数据转换为真正的数组:  
let arr = [12,45,97,9797,564,134,45642]
let set = new Set(arr)
console.log(set) // Set(7) {12, 45, 97, 9797, 564,...}
console.log(Array.from(set))  // (7) [12, 45, 97, 9797, 564, 134, 45642]


// 第二个参数的作用:
let arr1 = [12,45,97,9797,564,134,45642]
let set1 = new Set(arr)
console.log(Array.from(set1,item => item + 1)) // (7) [13, 46, 98, 9798, 565, 135, 45643]


// 要转换的是一个数组,则会返回一个一模一样的新数组:
let arr2 = [12,45,97,9797,564,134,45642]
console.log(Array.from(arr2)) // [12, 45, 97, 9797, 564, 134, 45642]
console.log(Array.from(arr2) === arr2) // false


// 第三个参数的作用:
 let obj = {
    '0': 1,
    '1': 5,
    '2': 6,
    length: 3
  }
  let one = {
    number(n) {
      return n + 5
    }
  }
  console.log(Array.from(obj,
    function (x) {
      return this.number(x)
    },
    one//表示function方法的this指向外界的one
  )); // (3) [6, 10, 11]

注意:

        将一个类数组对象转换为一个真正的数组,必须具备以下条件:
  1.该类数组对象必须具有length属性,用于指定数组的长度。如果没有length属性,那么转换后的数组是一个空数组。
  2.该类数组对象的属性名必须为数值型或字符串型的数字
  3.该类数组对象的属性名可以加引号,也可以不加引号

Array.isArray()

Array.isArray()用于判断传递的值是否是数组

console.log(Array.isArray([])) // true
console.log(Array.isArray({})) => false

Array.of()

Array.of()创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。
任意个参数,将按顺序成为返回数组中的元素。
返回值:新的 Array 实例。

console.log(Array.of(7)) // [7]
console.log(Array(7)) // [空 ã7]
console.log(Array.of(1, 2, 3)) // [1, 2, 3]
console.log(Array(1, 2, 3)) // [1, 2, 3]

Array.of()和Array的区别:
        Array.of(7)创建一个具有单个元素7的数组,而 Array(7)创建一个长度为7的空数组(注意:这是指一个有 7 个空位 (empty) 的数组,而不是由 7 个undefined组成的数组),Array方法只有当参数个数不少于2个时,Array()才会返回由参数组成的新数组。参数个数只有一个时,实际上是指定数组的长度。

Array.concat()

 Array.concat()方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。

//合并数组:  
let a1 = ['a', 'b', 'c']
let a2 = ['1', '2', '3']
let a3 = ['张三', '李四']
let a4 = a1.concat(a2, a3)
console.log(a4) // ['a', 'b', 'c', '1', '2', '3', '张三', '李四']

Array.copyWithin(target, start, end)

Array.copyWithin(target, start, end)浅复制数组的一部分到同一数组中的另一个位置,但复制后得到的数组不会超出原数组的长度
复制后,会替换掉你所书写的第一个参数的索引位置的数据,并往后延续,不改变数组长度的情况下,超出的部分将被截取
let arr = [1,2,3,4,5,6,7,8,9,10,11,12]
arr.copyWithin(8,2,5)会截取数组索引为2到4的数据替换掉数组arr[8]到arr[10]的数据
=> arr变为[1, 2, 3, 4, 5, 6, 7, 8, 3, 4, 5, 12]

参数说明:

target必需start可选end可选
复制到指定目标索引位置元素复制的起始位置停止复制的索引位置 (默认为 array.length)。如果为负值,表示倒数。注:不包含最后一个索引元素

let arr = ['a','b','c','d','e']
console.log(arr.copyWithin(2,0,4)) // ['a', 'b', 'a', 'b', 'c']
// 会改变原数组
let arr = ['1','2','3','4','5']
console.log(arr.copyWithin(1,3,4)) // ['1', '4', '3', '4', '5']
console.log(arr.copyWithin(0,3,4)) // ['4', '4', '3', '4', '5']

Array.every(function(currentValue,index,arr), thisValue)

Array.every()方法用于检测数组中的所有元素是否都满足指定条件(该条件为一个函数)。
Array.every()方法会遍历数组的每一项,如果有有一项不满足条件,则表达式返回false,剩余的项将不会再执行检测;如果遍历完数组后,每一项都符合条,则返回true。

function参数说明:

        第一个参数为一个回调函数,必传,数组中的每一项都会遍历执行该函数

currentValue必需index可选arr可选
当前项的值当前项的索引值当前项所属的数组对象

        第二个参数thisValue为可选参数,回调函数中的this会指向该参数对象。

let a1 = ['30', '40', '50']
let a2 = ['32', '40', '50']
console.log(a1.every(item => item % 10 == 0)) // true
console.log(a2.every(item => item % 10 == 0)) // false
//是完全的写法的时候要写return  
let a3 = [30, 40, 50]
let a4 = ['32', '40', '50']
let res1 = a3.every(function(item,index,arr) {
  return item % 10 == 0
})
let res2 = a4.every((item,index,arr) => {
  return item % 10 == 0
})

注意:

        1.Array.every() 不会对空数组进行检测
        2.Array.every() 不会改变原始数组

Array.fill(value,start,end)

Array.fill() 用一个固定值填充一个数组中从起始索引到终止索引内的全部元素,不包含结束索引

 返回值:数组,改变后的数组,会改变原数组

参数说明:

        

value必需start可选end可选
用于填充数组的值开始填充数组的索引(默认为 0)停止填充数组的索引(默认为 array.length)
var numbers = [1, 2, 3]
console.log(numbers.fill(1)) // [1, 1, 1]
console.log(numbers.fill(2, 0, 2)) // [2, 2, 1]
var numbers = [1, 2, 3]
console.log(numbers.fill(2, 0, 2)) // [2, 2, 3]

Array.filter(function(currentValue,index,arr), thisValue)

Array.filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
注意:

        1.Array.filter() 不会对空数组进行检测。
        2.Array.filter() 不会改变原始数组。

var arr = [1, 10, 20, 30]
var brr = arr.filter((item) => {
   return item > 10;
})
console.log(brr) // [20, 30]

Array.find()

Array.find()返回数组中满足提供的测试函数的第一个元素的值

let arr = [14, 23, 35, 56, 78, 97, 38]
let result = arr.find(item => item > 78)
console.log(result) // 97
function fn(element) {
  return element >= 15;
}
console.log([12, 5, 8, 130, 44].find(fn)) // 130

Array.findIndex()

Array.findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。

  function fn(element) {
    return element >= 555;
  }
  console.log([12, 5, 8, 130, 44].findIndex(fn)) // -1
  let arr = [32, 34, 54, 65, 87]
  console.log(arr.findIndex(item => item > 44)) // 2

Array.forEach(currentValue,index,arr), thisValue)

Array.forEach()方法对数组的每个元素执行一次提供的函数

 var items = ['item1', 'item2', 'item3'];
 var copy = [];
 items.forEach(function (item) {
   copy.push(item)
 });
 console.log(copy) // ['item1', 'item2', 'item3']

Array.includes(查找内容)

Array.includes()用来判断一个数组是否包含一个指定的值
返回值:true/false

let a = [1, 2, 3];
console.log(a.includes(2)) // true
console.log(a.includes(4)) // false

Array.indexOf(查找内容)

Array.indexOf()返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1

let a = [2, 9, 7, 8, 9]; 
a.indexOf(2);  // 0 
a.indexOf(6);  // -1
a.indexOf(7);  // 2
a.indexOf(8);  // 3
a.indexOf(9);  // 1

Array.lastIndexOf(查找内容)

Array.lastIndexOf()返回指定元素在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找

let a = [1, 2, 3];
console.log(a.lastIndexOf(1)) // 0
console.log(a.lastIndexOf(4)) // -1

Array.pop()

Array.pop()从数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度

let a = [1, 2, 3, 7];
console.log(a.length) // 4
console.log(a.pop()) // 7
console.log(a.length) // 3
console.log(a) // [1, 2, 3]

Array.push()

Array.push()将一个或多个元素添加到数组的末尾

let a = [1, 2, 3];
console.log(a.length) // 3
a.push(7)
console.log(a.length) // 4
console.log(a) //  [1, 2, 3, 7]

Array.shift()

Array.shift()从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度

let a = [1, 2, 3, 7];
console.log(a.length) // 4
console.log(a.shift()) // 1
console.log(a.length) // 3
console.log(a) // [2, 3, 7]

Array.unshift()

Array.unshift()将一个或多个元素添加到数组的开头,并返回新数组的长度

let a = [1, 2, 3, 7];
console.log(a.length) // 4
console.log(a.unshift(3)) // 5
console.log(a.length) // 5
console.log(a) // [3, 1, 2, 3, 7]

Array.toString()

Array.toString()返回一个字符串,表示指定的数组及其元素

let a = [1, 2, 3, 7];
console.log(a.length) // 4 
console.log(a.toString()) // 1,2,3,7

Array.join()

Array.join()将数组(或一个类数组对象)的所有元素连接到一个字符串中,  默认为 ","
返回值:一个由你的参数拼接好的字符串,不改变原数组

let a = ['Wind', 'Rain', 'Fire'];
a.join();
console.log(a) // 'Wind,Rain,Fire'

Array.reverse()

Array.reverse()方法将数组中元素的位置颠倒。
返回值:会改变原数组,返回一个颠倒顺序的数组

let a = [1, 2, 3, 7];
console.log(a.reverse()) // [7, 3, 2, 1]

Array.slice(start,end)

Array.slice(start,end)返回一个从开始到结束(不包括结束)选择的数组的一部分浅拷贝到一个新数组对象,不会改变原数组,会生成一个新数组

let a = [1, 2, 3, 4, 5, 6, 7];
console.log(a.slice(0)) // [1, 2, 3, 4, 5, 6, 7]
console.log(a.slice(0,2)) //  [1, 2]

Array.some(function(currentValue,index,arr), thisValue)

Array.some(function(currentValue,index,arr), thisValue)测试数组中的某些元素是否通过由提供的函数实现的测试。返回值:true/false

const isBiggerThan10 = (element, index, array) => {
    return element > 10;
}
console.log([2, 5, 8, 1, 4].some(isBiggerThan10)) // false
let arr = [1,2,3,4,5,6]
console.log(arr.some(item => item > 5)) // true

let arr = [1,2,3,4,5,6]
console.log(arr.some((item,index,arr) => {
  return item > 4
})) // true

Array.sort()

Array.sort()对数组的元素进行排序,并返回数组。
会改变原数组

let arr = [1,2,7,4,9,5,6]
console.log(arr.sort()) // [1, 2, 4, 5, 6, 7, 9]

Array.splice(start,length,新增数据)

Array.splice(start,length,新增数据)通过删除现有元素和/或添加新元素来更改一个数组的内容
会改变原数组

let arr = [1,2,7,4,9,5,6]
console.log(arr.splice(0)) // [1, 2, 7, 4, 9, 5, 6]

let arr = [1,2,7,4,9,5,6]
console.log(arr.splice(1,5)) // [2, 7, 4, 9, 5]

let arr = [1,2,7,4,9,5,6]
console.log(arr.splice(4,1,'6')) // [9]
console.log(arr) // [1, 2, 7, 4, "6", 5, 6]

let arr = [1,2,7,4,9,5,6]
console.log(arr.splice(4,1,[1,2,3])) // [9]
console.log(arr) // [1, 2, 7, 4, Array(3), 5, 6]

Array.toLocaleString()

Array.toLocaleString()返回一个字符串表示数组中的元素。数组中的元素将使用各自的 toLocaleString 方法转成字符串,这些字符串将使用一个特定语言环境的字符串(例如一个逗号",")隔开

let arr = [1, 2, 7, 4, 9, 5, 6]
var number = 1337;
var myArr = [number, arr, "foo"];
var str = myArr.toLocaleString();
console.log(str) // 1,337,1,2,7,4,9,5,6,foo
console.log(number.toLocaleString()) // 1,337

Array.map(function(currentValue,index,arr), thisValue)

Array.map(function(currentValue,index,arr), thisValue)创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果

var arr = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4];
var str1 = arr.map(item => item+1)
console.log(str1) // [2, 3, 2, 3, 4, 6, 5, 6, 4, 5, 5, 5, 5]
var str2 = arr.forEach(item => item+1)
console.log(str2) // undefined

forEach和map的区别:
        1.map方法会返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
        2.forEach方法返回值则永远是undefined。
        3.forEach()执行的速度相比map慢了70%。

Array.reduce(function(currentValue,index,arr), thisValue)

Array.reduce(function(currentValue,index,arr), thisValue)累加器和数组中的每个元素(从左到右)应用一个函数
第一个参数是一个callback,用于针对数组项的操作;第二个参数则是传入的初始值

//累加:
var total = [0, 1, 2, 3].reduce(function (sum, value) {
    return sum + value;
}, 0);
console.log(total) // 6

//将二维数组转换成一维:
var a= [[0,1],[2,3],[4,5],[6,7],[8,9]];
var str = a.reduce(function(prev,cur){
	return prev.concat(cur)
})
console.log(str) // [0,1, 2, 3, 4, 5, 6, 7, 8, 9]

//数组去重:
var arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
var str = arr.sort().reduce((prev, cur)=>{
    if(prev.length===0 || prev[prev.length-1]!==cur){
        prev.push(cur);
    }
    return prev;
}, []);
console.log(str) // [1, 2, 3, 4, 5]

Array.reduceRight()

Array.reduceRight()累加器和数组中的每个元素(从右到左)应用一个函数
第一个参数是一个callback,用于针对数组项的操作;第二个参数则是传入的初始值

//累加:
var total = [0, 1, 2, 3].reduceRight(function (sum, value) {
    return sum + value;
}, 0);
console.log(total) // 6

//二维数组转换为一维数组:  
let num = [
    [0, 1], 
    [2, 3],
    [4, 5]
].reduceRight((a, b) => {
    return a.concat(b);
}, []);
console.log(num) // [4, 5, 2, 3, 0, 1]

//数组去重:
var arr = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4];
var str = arr.sort().reduceRight((prev, cur) => {
   if (prev.length === 0 || prev[prev.length - 1] !== cur) {
      prev.push(cur);
   }
   return prev;
}, []);
console.log(str) // [5, 4, 3, 2, 1]

不改变原数组的方法

  • Array.every()
  • Array.filter()
  • Array.forEach()
  • Array.indexOf()
  • Array.join()
  • Array.lastIndexOf()
  • Array.map()
  • Array.slice()
  • Array.some()
  • Array.reduce()
  • Array.reduceRight()
  • Array.concat()
  • Array.toString()
  • Array.toLocaleString()
  • Array.isArray()
  • Array.from()
  • Array.of()
  • Array.find()
  • Array.findIndex()
  • Array.includes()

改变原数组的方法

  •     Array.splice()
  •     Array.reverse()
  •     Array.fill()
  •     Array.shift()
  •     Array.pop()
  •     Array.push()
  •     Array.unshift()
  •     Array.copyWithin()
  •     Array.sort()
  •     Array.length()

数组去重

一、set+Array.from()
Set对象:是值的集合,你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即Set中的元素是唯一的。
Array.from() 方法:对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。

const arr = [1, 2, 2, 'abc', 'abc', true, true, false, false, undefined, undefined, NaN, NaN]
console.log(new Set(arr)) => Set(7) {1, 2, 'abc', true, false, …}
console.log(Array.from(new Set(arr))) // (7) [1, 2, 'abc', true, false, undefined, NaN]

二、利用两层循环+数组的splice方法
通过两层循环对数组元素进行逐一比较,然后通过splice方法来删除重复的元素。此方法对NaN是无法进行去重的,因为进行比较时NaN !== NaN。

function removeDuplicate(arr) {
  let len = arr.length
  for (let i = 0; i < len; i++) {
    for (let j = i + 1; j < len; j++) {
      if (arr[i] === arr[j]) {
        arr.splice(j, 1)
        len-- // 减少循环次数提高性能
        j-- // 保证j的值自加后不变
      }
    }
  }
  return arr
}

const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN, NaN ]

三、利用数组的indexOf方法
新建一个空数组,遍历需要去重的数组,将数组元素存入新数组中,存放前判断数组中是否已经含有当前元素,没有则存入。此方法也无法对NaN去重。

indexOf() 方法:返回调用它的String对象中第一次出现的指定值的索引,从 fromIndex 处进行搜索。如果未找到该值,则返回 -1。

function removeDuplicate(arr) {
  const newArr = []
  arr.forEach(item => {
    if (newArr.indexOf(item) === -1) {
      newArr.push(item)
    }
  })
  return newArr // 返回一个新数组
}

const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN, NaN ]

四、利用数组的includes方法
此方法逻辑与indexOf方法去重异曲同工,只是用includes方法来判断是否包含重复元素。
includes()方法:用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。
注意:为什么includes能够检测到数组中包含NaN,其涉及到includes底层的实现。如下图为includes实现的部分代码,在进行判断是否包含某元素时会调用sameValueZero方法进行比较,如果为NaN,则会使用isNaN()进行转化。

function removeDuplicate(arr) {
  const newArr = []
  arr.forEach(item => {
    if (!newArr.includes(item)) {
      newArr.push(item)
    }
  })
  return newArr
}

const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]

五、利用数组的filter()+indexOf()
filter方法会对满足条件的元素存放到一个新数组中,结合indexOf方法进行判断。
filter() 方法:会创建一个新数组,其包含通过所提供函数实现的测试的所有元素。
这里的输出结果中不包含NaN,是因为indexOf()无法对NaN进行判断,即arr.indexOf(item) === index返回结果为false。

function removeDuplicate(arr) {
  return arr.filter((item, index) => {
    return arr.indexOf(item) === index
  })
}

const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined ]
const testArr = [1, 'a', NaN]
console.log(testArr.indexOf(NaN)) // -1

六、利用Map()
Map对象是JavaScript提供的一种数据结构,结构为键值对形式,将数组元素作为map的键存入,然后结合has()和set()方法判断键是否重复。

Map 对象:用于保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值)都可以作为一个键或一个值。
注意:使用Map()也可对NaN去重,原因是Map进行判断时认为NaN是与NaN相等的,剩下所有其它的值是根据 === 运算符的结果判断是否相等。

function removeDuplicate(arr) {
  const map = new Map()
  const newArr = []

  arr.forEach(item => {
    if (!map.has(item)) { // has()用于判断map是否包为item的属性值
      map.set(item, true) // 使用set()将item设置到map中,并设置其属性值为true
      newArr.push(item)
    }
  })
  return newArr
}

const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]

七、利用对象
其实现思想和Map()是差不多的,主要是利用了对象的属性名不可重复这一特性。

function removeDuplicate(arr) {
  const newArr = []
  const obj = {}

  arr.forEach(item => {
    if (!obj[item]) {
      newArr.push(item)
      obj[item] = true
    }
  })
  return newArr
}

const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]

八、利用Array.reduce()方法

var arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
var str = arr.sort().reduce((prev, cur)=>{
    if(prev.length===0 || prev[prev.length-1]!==cur){
        prev.push(cur);
    }
    return prev;
}, []);
console.log(str) // [1, 2, 3, 4, 5]

九、利用Array.reduceRight()方法

var arr = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4];
var str = arr.sort().reduceRight((prev, cur) => {
   if (prev.length === 0 || prev[prev.length - 1] !== cur) {
      prev.push(cur);
   }
   return prev;
}, []);
console.log(str) // [5, 4, 3, 2, 1]

数组置空

var arr = new Array(1,2,3);
arr.length = 0;
var arr = new Array(1,2,3);
arr.splice(0, arr.length);
var arr = new Array(1,2,3);
arr = [];

;