JavaScript - 数组

257 阅读5分钟

【数组】数组扁平化

数组扁平化是指将一个多维数组变为一维数组 [1, [2, 3, [4, 5]]] ------> [1, 2, 3, 4, 5]

1、flat API

flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。 **参数:depth 可选,**指定要提取嵌套数组的结构深度,默认值为 1。 使用 Infinity,可展开任意深度的嵌套数组。 flat() 方法会移除数组中的空项。

const arr = [0, 1, 2, [[[3, 4]]]];

console.log(arr.flat(Infinity));
// expected output: [0, 1, 2, 3, 4]

2、toString & split

会改变数组元素的类型。

const test = [1, [2, 3, [4, 5]]] 

arr.toString().split(',').map(item => item - 0)

3、递归

循环数组,判断 arr[i] 是否是数组,是数组的话再次调用此函数。

const flatten = function(arr) {
    let res = []
    arr.forEach(ele => {
        if(Array.isArray(ele)){
           res = res.concat(flatten(ele))
        }else{
           res.push(ele) 
        }
    })
    return res
};

const test = [1, [2, 3, [4, 5]]] 

flatten(test) // [1, 2, 3, 4, 5]

4、使用reduce函数

reduce方法对数组中的每个元素执行一个reducer函数,将其结果汇总为单个返回值。 arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue]) arr.reduce(callback( 累计器, 当前值 [, 当前索引 [, 源数组]])[, 初始值])

const flatten = (arr) => {
  let res = []
  res = arr.reduce((accumulator, currentValue) => {
    return accumulator.concat(Array.isArray(currentValue)? flatten(currentValue) : currentValue)
  },[])
  return res
}

const test = [1, [2, 3, [4, 5]]] 

flatten(test) // [1, 2, 3, 4, 5]

PS: reduce求和

const arr = [1, 2, 3, 4, 5]
const sum = arr.reduce((acc, current) => acc + current, 0)
console.log(sum) // 15

PS: reduce求最大值

const arr = [1, 2, 3, 4, 5]
const sum = arr.reduce((acc, current) => acc >= current? acc : current, 0)
console.log(sum) // 15

5、ES6 扩展运算符 ...

一层一层将数组展开(类似于剥洋葱)

const flatten = (arr) => {
    while (arr.some(item => Array.isArray(item))) {
        arr = [].concat(...arr) // 给原数组重新赋值
    }
    return arr
}

const test = [1, [2, 3, [4, 5]]] 

flatten(test) // [1, 2, 3, 4, 5]

【数组】数组去重

1、使用reduce函数去重

const filter = (arr) => {
  let result = []
  result = arr.reduce((accumulator, currentValue) => {
    if(!accumulator.includes(currentValue)){
      accumulator.push(currentValue)
    }
    return accumulator
  },[])
  return result
}

const test = [1, 1, 2, 3, 3, 4, 5] 

filter(test) // [1, 2, 3, 4, 5]

2、利用对象的属性不能相同的特点去重

let arr = [1,3,8,9,3,5,4,4,6,6,2]
function unique(arr) {
  let result = []
  let obj = {}
  arr.forEach(ele => {
    if(!obj.hasOwnProperty(ele)){
      obj[ele] = 1
      result.push(ele)
    }
  })
  return result
}
console.log(unique(arr)) // [1, 3, 8, 9, 5, 4, 6, 2]

3、用ES6中的Map方法去重

let arr = [1,3,8,9,3,5,4,4,6,6,2,9,11]
function unique(arr) {
  return [...new Set(arr)]
}
console.log(unique(arr)) // [1, 3, 8, 9, 5, 4, 6, 2, 11]

4、遍历去重

let arr = [1,3,8,9,3,5,4,4,6,6,2,9]
function unique(arr) {
  let result = []
  arr.forEach(ele => {
    if(!result.includes(ele)){
      result.push(ele)
    }
  })
  return result
}
console.log(unique(arr)) // [1, 3, 8, 9, 5, 4, 6, 2]

【数组】如何确认变量类型是数组

1、Array.isArray

const arr = [1,2,3,4,5]
const obj = {
  "name": "sunlz",
  "age": 18,
}
console.log(Array.isArray(arr), Array.isArray(obj)) // true false

2、ary instanceof Array

const arr = [1,2,3,4,5]
const obj = {
  "name": "sunlz",
  "age": 18,
}
console.log(arr instanceof Array) // true
console.log(obj instanceof Array) // false
console.log(obj instanceof Object) // true

3、原型链方法 Object.prototype.toString

Object.prototype.toString.call() // "[object Undefined]"
Object.prototype.toString.call({}) // "[object Object]"
Object.prototype.toString.call([]) // "[object Array]"
Object.prototype.toString.call('') // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call(/abc/) // "[object RegExp]"
Object.prototype.toString.call(()=>{}) // "[object Function]"

4、constructor

const arr = [1,2,3,4,5]
const obj = {
  "name": "sunlz",
  "age": 18,
}
console.log(arr.constructor === Array) // true
console.log(obj.constructor === Array) // false

【数组】数组创建方式

1、字面量

var arr1 = [1,2,3,4,5] 

console.log(arr1) // [1, 2, 3, 4, 5]

2、构造函数

var arr2 = new Array("name", "age");

console.log(arr2) // ["name", "age"]

3、数组表达式

var arr3 = Array("bus", "boat");

console.log(arr3) // ["bus", "boat"]

【数组】数组的拷贝

1、array.slice(start, [end]) 返回新数组

var arr1 = [1, 2, 3];
var arr2 = arr1.slice(0);

console.log(arr1 === arr2); // false

2、array.concat() 不改变原数组,返回新数组

var arr1 = [1, 2, 3];
var arr2 = arr1.concat();

console.log(arr1 === arr2); // false

3、循环遍历实现

var arr1 = [1, 2, 3];
var arr2 = [];
arr1.forEach(ele => {
  arr2.push(ele)
})
console.log(arr1 === arr2); // false

【数组】求数组最大值方法

1、es6拓展运算符...

var arr = [-1, 1, 101, -52, 10, 1001, 1001]
var maxNum = Math.max(...arr)
console.log(maxNum) // 1001

2、apply

var arr = [-1, 1, 101, -52, 10, 1001, 1001]
var maxNum = Math.max.apply(null, arr)
console.log(maxNum) // 1001

3、for循环

var arr = [-1, 1, 101, -52, 10, 1001, 1001]
var maxNum = -1
arr.forEach(ele => {
  if(ele > maxNum){
    maxNum = ele
  }
})
console.log(maxNum) // 1001

4、数组sort()

var arr = [-1, 1, 101, -52, 10, 1001, 1001]
var maxNumList = arr.sort(function(a,b){
  return a-b
})
var maxNum = maxNumList[maxNumList.length - 1]
console.log(maxNum) // 1001

【数组】将类数组转为数组

1、类数组的定义

  • 拥有length属性,其它属性(索引)为非负整数(对象中的索引会被当做字符串来处理)
  • 不具有数组所具有的方法;
    • javascript中常见的类数组有 arguments对象和 DOM方法的返回结果。

2、循环遍历

arr = []
for (i = 0; i < arrayLike.length; i++) {    
  arr.push(arrayLike[i])
}

3、使用Array原型中的方法

1.slice方法

Array.prototype.slice.call(arrayLike)

用call函数让类数组对象使用了Array原型的slice方法,这会截取类数组内所有项的value值形成一个新的数组。 ​

2.concat方法

Array.prototype.concat.apply([], arrayLike)

用apply函数修改指向,让一个空数组和类数组进行连接,这是会让空数组和类数组的value进行连接。 ​

3.splice方法

Array.prototype.splice.call(arrayLike, 0)

用call函数让类数组使用Array原型的splice方法而不进行裁切,得到数组。 ​

4、ES6的from方法

arr = Array.from(arrayLike);

【数组】获取两个数组的交集/并集/补集/差集

1、交集

const arr1 = [1,2,3,4,5],
      arr2 = [5,6,7,8,9];

const jiaoji = arr1.filter(ele => arr2.includes(ele))
console.log(jiaoji) // [5]

2、并集

const arr1 = [1,2,3,4,5],
      arr2 = [5,6,7,8,9];

const bingji = arr1.concat(arr2.filter(ele => !arr1.includes(ele)))
console.log(bingji) // [1, 2, 3, 4, 5, 6, 7, 8, 9]

3、补集

const arr1 = [1,2,3,4,5],
      arr2 = [5,6,7,8,9];

let arr1buji = arr1.filter(ele => !arr2.includes(ele))
let arr2buji = arr2.filter(ele => !arr1.includes(ele))
let buji = arr1buji.concat(arr2buji)
console.log(buji) // [1, 2, 3, 4, 6, 7, 8, 9]

4、差集

const arr1 = [1,2,3,4,5],
      arr2 = [5,6,7,8,9];

let chaji = arr1.filter(ele => !arr2.includes(ele))
console.log(chaji) // [1, 2, 3, 4]

5、手绘图解交集/并集/补集/差集

IMG_20210731_181236.jpg

【数组】置空数组

设置数组的length = 0

const arr1 = [1,2,3,4,5]
arr1.length = 0

console.log(arr1) // []

【数组】从数组中删除虚值

在 JS 中,虚值有 false, 0, '', null, NaN, undefined

const arr1 = [1,2,3,4,5,false, 0, '', null, NaN, undefined]
const result = arr1.filter(ele => !!ele)
console.log(result) // [1, 2, 3, 4, 5]

【数组】生成类似[1-100]这样的的数组

1、Array.from

var arr = Array.from({length:100}, (v,k) => k);
console.log(arr); // [0, 99]

2、new Array fill

var arr = new Array(100).fill(0).map((ele,index) => index + 1);
console.log(arr); // [1, 100]

3、巧用Array.keys()

var arr = [...new Array(100).keys()];
console.log(arr);  // [0, 99]