0%

数组的常用方法

数组常用方法

MDN Array

Array 对象的方法

Array.from()

  • 从类数组对象或者可迭代对象中创建一个新的数组实例
  • 返回值 —— 一个新数组
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // 1.从字符串生成
    Array.from('foo') // ['f', 'o', 'o']

    // 2.map 函数生成
    Array.from([1, 2, 3], x => x + x) // [2, 4, 6]

    // 3.从类数组生成
    function f() {
    return Array.from(arguments)
    }

    f(1, 2, 3) // [1, 2, 3]

    let btns = document.getElementsByTagName('button')
    Array.from(btns).forEach(function (item, index) {
    console.log(item)
    })

Array.isArray()

  • 用来判断某个变量是否是一个数组对象
  • 返回值 —— true /false
    1
    2
    3
    4
    5
    Array.isArray([]) // true

    Array.isArray(Array.prototype) // true

    Array.isArray(null) //false

Array.of()

  • 创建一个具有可变数量参数的新数组实例
  • 返回值 —— 一个新数组

⚠️ 与 Array() 的区别

  • 当传递单个数字参数时,Array.of() 是创建一个只有该数字的数组,而 Array() 是创建一个长度为该数字的空数组
    1
    2
    3
    4
    5
    Array.of(7)       // [7] 
    Array.of(1, 2, 3) // [1, 2, 3]

    Array(7) // [ , , , , , , ]
    Array(1, 2, 3) // [1, 2, 3]

Array 实例的方法

直接影响原数组的方法

push()

  • 向数组最后添加一个或多个元素
  • 返回值 —— 新数组的长度
    1
    2
    3
    4
    5
    6
    7
    var arr = [1, 2]
    arr.push(3)
    console.log(arr) // 1, 2, 3

    var ret = arr.push(4, 5)
    console.log(arr) // 1, 2, 3, 4, 5
    console.log(ret) // 5

pop()

  • pop()
    • 删除数组最后一个元素
    • 返回值 —— 被删除的元素
      1
      2
      3
      4
      var arr1 = [1, 2, 3]

      var ret = arr1.pop()
      console.log(ret, arr1) // 3 [1, 2]

unshift()

  • 向数组的最前面添加一个或多个元素
  • 返回值 —— 新数组的长度
    1
    2
    3
    var arr2 = [1, 2]
    var ret = arr2.unshift(3, 4)
    cosnole.log(ret, arr2) // 4 [3, 4, 1, 2]

shift()

  • 删除数组的第一个元素
  • 返回值 —— 被删除的元素
    1
    2
    3
    var arr3 = [1, 2]
    var ret = arr3.shift()
    cosnole.log(ret, arr3) // 1 [2]

splice(start, howmany[, item1… ])

  • 可以实现数组的 增 / 删 / 改

  • 第一个参数 —— 开始索引
    第二个参数 —— 删除的个数
    第三个(及以后的)参数 —— 从删除位置插入新元素

  • 返回值 —— 被删除的元素数组, 如果没有被删除的元素返回空数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 如果只有两个参数,就是删除操作
    var arr = ['angel', 'clown', 'drum', 'mandarin', 'sturgeon']
    var removed = arr.splice(3, 1)
    console.log(arr, removed) // ['angel', 'clown', 'drum', 'sturgeon'] ['mandarin']

    // 如果有三个以上参数,且第二个参数为 0,就是新增操作
    var arr = [1, 2, 3]
    var removed = arr.splice(1, 0, 4)
    console.log(arr, removed) // [1, 4, 2, 3] []

    // 如果有三个以上参数,且第二个参数不为 0,就是改操作
    var arr = [1, 2, 3]
    var removed = arr.splice(1, 2, 4)
    console.log(arr, removed) // [1, 4] [2, 3]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // 数组去重
    var arr = [1, 3, 5, 1, 2, 2, 4, 7, 5]

    for(var i = 0; i < arr.length - 1; i++) {
    for (var j = i + 1; j < arr.length; j++) {
    if (arr[j] == arr[i]) {
    // 如果相等, 则证明出现了重复元素, 则删除 j 位置对应的元素
    arr.splice(j, 1)

    // 当删除了 j 所在位置的元素后, 后边的元素会自动补位
    // 此时将不再比较这个位置的元素,我们需要在比较一次 j 所在位置的元素
    j--
    }
    }
    }

reverse()

反转数组

  • 返回值 —— 反转后的新数组
    1
    2
    3
    var arr = [1, 2, 3]
    arr.reverse()
    console.log(arr) // [3, 2, 1]

sort([fn])

数组排序

  • 默认按照 Unicode 编码排序

    • 对数字排序,需要指定比较函数
    • 对对象元素按某个属性排序,也要指定排序函数
  • 会直接修改原数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    // 1. 非数字排序
    var arr = ['abc', 'acd', 'b']
    arr.sort() // [abc', 'acd', 'b']

    // 2. 数字排序 - 要指定比较函数
    var arr = [1, 2, 19, 29, 3]
    arr.sort((a, b) => a - b) // 升序排列

    // 3. 按对象的某个属性排序
    var items = [
    { name: 'Edward', value: 21 },
    { name: 'Sharpe', value: 37 },
    { name: 'And', value: 45 },
    { name: 'The', value: -12 },
    { name: 'Magnetic' },
    { name: 'Zeros', value: 37 }
    ]

    // sort by value
    items.sort(function (a, b) {
    return (a.value - b.value)
    })

    // sort by name
    items.sort(function(a, b) {
    var nameA = a.name.toUpperCase() // ignore upper and lowercase
    var nameB = b.name.toUpperCase() // ignore upper and lowercase
    return nameA - nameB
    })

不影响原数组的方法

slice(start[, end])

  • 从数组中 提取指定元素
  • 参数是索引, 从开始到结束 (包含开始,不包含结束)
    • 如果传递负值, 则从后往前数
  • 返回值 —— 截取的新数组
    1
    2
    3
    4
    5
    var arr = [1, 2, 3, 4, 5]

    var newArr = arr.slice(1, 4) // [2, 3, 4]

    var newArr1 = arr.slice(1, -1) // [2, 3, 4] -1 代表最后一个元素的索引

concat()

  • 连接两个或多个数组
  • 返回值 —— 新数组
    1
    var ret = arr1.concat(arr2, arr3)

join()

  • 将数组转为字符串
  • 可以指定一个字符作为数组元素连接符 (不指定则默认使用逗号连接)
  • 返回值 —— 字符串
    1
    2
    var arr = [1, 2, 3]
    var ret = arr.join('-') // '1-2-3'

遍历方法

forEach(function(item[, i, arr]) { })

  • 遍历数组 (将数组中的每个元素都读取出来)
  • 需要一个函数作为参数
    • 数组中有几个元素, 函数就会执行几次, 每次执行时, 浏览器会把遍历到的元素以实参的形式传递进来;
    • 我们可以定义形参, 来读取这些内容
    • 第一个参数 —— 当前正在遍历的元素
      第二个参数 —— 当前正在遍历的元素的索引
      第三个参数 —— 当前数组
  • 返回值 —— undefined (无返回值,默认返回 undefined)
    1
    2
    3
    4
    var arr4 = [1, 2, 3]
    arr4.forEach(function (item, i) {
    console.log(item, i)
    })

map(function (item, index) {})

  • 遍历数组
  • 返回值 —— 由 返回值 生成的新数组
    • 新数组和原数组长度一致, 一对一的关系
    • ⚠️常用来对请求得到的数据进行进一步的筛选(只取我们需要用到的属性
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      var arr = [1, 2, 3]
      var arr1 = arr.map(function (item, index) {
      return item + 10
      });
      console.log(arr, arr1) [1, 2, 3] [11, 12, 13]

      const ret = response.data.items.map(item => ({
      name: item.user_name,
      avatar: item.pic
      }))

filter(function (item, index) {})

  • 遍历 过滤出一个新的子数组,
  • 返回值 —— 条件为 true 的值组成的新数组
    • 新数组是原数组的子数组, 长度可以比原数组小
      1
      2
      3
      4
      5
      var arr = [1, 2, 3, 6]
      var arr2 = arr.filter(function (item, index) {
      return item > 4
      })
      console.log(arr, arr2) [1, 2, 3, 6] [6]

数组的查找方法

find(function (item, index) { return true })

  • 找出第一个满足条件的值
  • 返回值 —— 满足条件的第一个值或者 undefined (没找到)
    1
    2
    3
    let result = arr.find(function (item, index) {
    return item > 4
    })

findIndex(function (item, index) { return true })

  • 找出第一个满足条件的值的索引
  • 返回值 —— 满足条件的第一个值的索引或者 -1 (没有)
    1
    2
    3
    let resultIndex = arr.findIndex(function (item, index) {
    return item > 4
    })

some(function (item, index) { return true })

  • 数组中是否有符合条件的值
  • 返回值 —— true /false
    1
    2
    3
    4
    5
    6
    7
    // 根据 id 删除元素
    arr.some((item, index) => {
    if (item.id === 4) {
    arr.splice(index, 1)
    return true // 找到符合条件的后立即中止
    }
    })

indexOf(value)

  • 得到元素在数组中的第一个下标
  • 返回值 —— 下标

lastIndexOf(value)

  • 得到元素在数组中的最后一个下标
  • 返回值 —— 下标
    1
    2
    3
    4
    var arr = [1, 4, 6, 2, 5, 6]
    console.log(arr.indexOf(6)) //2

    console.log(arr.lastIndexOf(6)) //5

includes(val)

  • 判断一个数组是否包含一个指定的值
  • 返回值 —— true / false
    1
    2
    3
    const array1 = [1, 2, 3]

    console.log(array1.includes(2)) // true

数组累加 reduce()

1
2
3
4
5
6
arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
// 1. accumulator (acc) (累计器)
// 2. currentValue (cur) (当前值)
// 3. Current Index (idx) (当前索引)
// 4. Source Array (src) (源数组)
// 5. initialValue (初始值)

参考

  • 函数累计处理的结果
  • 返回值 —— 累计的结果
  • 返回值的类型 —— initialValue 的类型(最好提供),如果未指定 initialValue,返回值类型由数组元素决定
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // 1. 求和
    var total = [ 0, 1, 2, 3 ].reduce(( acc, cur ) => acc + cur, 0)

    // 2. 二维数组转一维数组
    var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
    function(a, b) {
    return a.concat(b);
    },
    []
    );
    // flattened is [0, 1, 2, 3, 4, 5]

    // 3. 数组中元素出现的次数
    var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];

    var countedNames = names.reduce(function (allNames, name) {
    if (name in allNames) {
    allNames[name]++;
    }
    else {
    allNames[name] = 1;
    }
    return allNames;
    }, {});
    // countedNames is:
    // { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }

回调函数第一次执行时,accumulatorcurrentValue的取值有两种情况:

​ 如果调用reduce()时提供了initialValueaccumulator取值为initialValuecurrentValue取数组中的第一个值

​ 如果没有提供 initialValue,那么accumulator取数组中的第一个值,currentValue取数组中的第二个值

some 和 forEach 的区别

  1. 返回值不同

    • some 返回 true/false, forEach 返回 undefied
  2. 遍历机制不同

    • some 回调内如果指明了 return true,则当前遍历会终止
    • forEach 则会从头到尾遍历每一个元素
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      var arr = ["red", "green", "blue", "pink", "red"];
      // 1. forEach迭代 遍历
      arr.forEach(function(item) {
      if (item == 'green') {
      console.log('找到了该元素');
      return true; // 在forEach 里面 return 不会终止迭代
      }
      console.log(11);
      })

      // 如果查询数组中唯一的元素, 用some方法更合适
      arr.some(function(item) {
      if (item == "red") {
      console.log("找到了该元素:" + item);
      return true; // 在some 里面 遇到 return true 就是终止遍历 迭代效率更高
      }
      console.log(11);
      });

总结数组常用方法

方法名 回调的返回值 方法的返回值
map 算术表达式*(item + 2)* / 任意类型 由回调的返回值生成新的数组
filter 条件表达式 / true (if(){…return true}) 由使回调的返回值为 true 的数组元素生成新的数组
find 条件表达式 / true (if(){…return true}) 使回调的返回值为 true 的数组元素
findIndex 同上 使回调的返回值为 true 的数组元素的索引
some 同上 true/false
forEach 不需要返回值 (可以指定,但没有意义) undefined
sort a - b (升序) / b - a (降序) undefined

数组常见算法

只取一个数组中元素的部分属性生成一个新数组

1
2
3
// 数组 result 的每个元素为一个对象 { name: 'zs', age: 18, id: 1, gender: 1 }
// 求生成一个新数组,只包含 name 和 id 属性
const newResult = result.map(item => ({ name: item.name, id: item.id }))

一维数组变二维数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// arr1 是一维数组,由 arr1 一个生成二维数组,二维数组的每个元素最大长度为 8
const arr1 = [{}, {}, ...,{}]

function getArr() {
let arr = []
let innerArr = []
arr1.forEach(item => {
// 如果内部数组是空的,塞入外部数组
if (innerArr.length === 0) {
arr.push(innerArr)
}

innerArr.push(item)

// 内部数组塞满后立即置空
if (innerArr.length === 8) {
innerArr = []
}

})
return arr
}

多条件过滤

1
2
3
4
5
6
7
8
9
10
// 数组 ratings 存的是评论数据
// 每条评论有属性 rateType 0-满意 1-不满意;text-评论内容
// 需要根据 ‘全部’‘满意’‘不满意’ 以及 ‘只看有内容的评论’ 对数组进行过滤

let selectType = 2 // 自定义变量表示选中的类型,可根据选择重新设置 0-满意 1-不满意 2-全部
let onlyText = false // 自定义变量表示是否只看有内容的评论
const filterArr = ratings.filter(item => {
return (selectType === 2 || item.rateType === selectType) &&
(!onlyText || text.length >0)
})