博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS常用数组操作全解析
阅读量:5934 次
发布时间:2019-06-19

本文共 10757 字,大约阅读时间需要 35 分钟。

concat() 方法用于连接两个或多个数组。
let arr1 = [1, 3, 4, 5]let arr2 = ['11', '1']let arr3 = [{ a: 1 }, { b: 2 }]let all = arr1.concat(arr2).concat(arr3)console.log(all) // [1, 3, 4, 5, "11", "1", {…}, {…}]复制代码
concat()方法,不会改变原数组本身

join(separator)把数组中每一项提取出来并用指定字符分割组成字符串
let arr1 = [1, 3, 4, 5, [1, 2, 3]]let arr2 = ['11', '1']let arr3 = [{ a: 1 }, { b: 2 }]let all = arr1.concat(arr2).concat(arr3)let str = all.join('v')console.log(str) // 1v3v4v5v1,2,3v11v1v[object Object]v[object Object]复制代码

separator为join方法暴露的参数,默认为','。**注意:**join可以提取String和Number但是无法解析对象中的数据


pop()删除数组最后一项,并返回被删除项,如果数组长度为0,则返回undefined
let arr1 = [0, 1, 2, 3, 4]let str = arr1.pop()console.log(str)	// 4console.log(arr1)	// [0, 1, 2, 3]复制代码

**注意:**pop()会改变源数组


push()方法可向数组的末尾添加一个或多个元素,并返回新的长度
let arr1 = [0, 1, 2, 3, 4]let str = arr1.push([5, 6])console.log(str)	// 6console.log(arr1) // [0, 1, 2, 3, 4, Array(2)]复制代码

**注意:**push()后向数组末尾添加指定数据,无论他什么类型,即使是NaN也会切只会占据数组中一个位置


reverse()颠倒数组中元素位置
let arr1 = [0, 1, 2, 3, 4]let str = arr1.reverse()console.log(str)	// [4, 3, 2, 1, 0]console.log(arr1)	// [4, 3, 2, 1, 0]复制代码

**注意:**此操作会改变源数组


shift()删除数组第一个元素,并返回被删除元素
let arr1 = [0, 1, 2, 3, 4]let str = arr1.shift()console.log(str)	// 0console.log(arr1)	// [1, 2, 3, 4]复制代码

**注意:**此操作会改变源数组


slice(start, end)从已有数组中选定一个范围组成子数组
let arr1 = [0, 1, 2, 3, 4]let arr2 = arr1.slice(1, 3)let arr3 = arr1.slice(-1)let arr4 = arr1.slice(1, -3)console.log(arr1)	// [0, 1, 2, 3, 4]console.log(arr2)	// [1, 2]console.log(arr3)	// [4]console.log(arr4)	// [1]复制代码

注意: start为必填项,确定开始位置,正数为顺序查询,负数为倒序查询;end为选填项,确定结束位置,默认为至最后一项


sort(sortby)对数组进行排序
**普通数组**sortNumber (a, b) {    return a - b},learnArray () {    let arr1 = ['10', '131', '234', '111', '20', '002', '0071']    console.log(arr1.sort())	// ["002", "0071", "10", "111", "131", "20", "234"]    console.log(arr1.sort(this.sortNumber))	// ["002", "10", "20", "0071", "111", "131", "234"]}**数组中的对象未处理前无法排序**learnArray () {    let arr = []    for (let i = 0; i < 5; i++) {        arr.push({i: i * Math.random()})        console.log(arr[i], arr[i].length)    }    console.log(arr.sort())    // 0:{i: 0}    // 1:{i: 0.16355624558752946}    // 2:{i: 1.7387739842785384}    // 3:{i: 0.3757190308241345}    // 4:{i: 3.160518025347579}}**经过特殊处理后的数组**sortNumber (a, b) {    let obj1 = a['i']    let obj2 = b['i']    return obj2 - obj1},learnArray () {    let arr = []    for (let i = 0; i < 5; i++) {        arr.push({i: i * Math.random()})        console.log(arr[i], arr[i].length)    }    console.log(arr.sort())    // 0:{i: 3.8106310267596397}    // 1:{i: 1.3285710809611437}    // 2:{i: 1.0776123310362173}    // 3:{i: 0.9429327310688747}    // 4:{i: 0}    console.log(arr.sort(this.sortNumber))    // 0:{i: 3.8106310267596397}    // 1:{i: 1.3285710809611437}    // 2:{i: 1.0776123310362173}    // 3:{i: 0.9429327310688747}    // 4:{i: 0}}复制代码

**注意:**sort()接受一个函数作为排序条件,默认按照字母顺序排列,函数的返回值应该是一个比较的结果,正数(正序)、负数(倒序)、或NAN(走默认排序),比较对象应该为由数字、字母任意组成的字符串,如果为sort传递了排序条件,默认排序会继承


splice(index,howmany,item1,.....,itemX)从数组中添加/删除元素
let arr = []let arr1 = arr.splice(0, 0, 1)console.log(arr)		// [1]console.log(arr1)		// []复制代码

index为起始位置,howmany为要删除项目数量,可以为0,item要添加的元素,splice方法会返回被删除的元素,并会改变原数组


toString将数组转换为对象并返回

结果与没有参数的join()方法一致,不会改变源数组


unshift在数组开头添加一个元素,并返回新长度

unshift会改变源数组,可以通过arr.unshift()拿到arr的长度


forEach
let arr1 = [1, 2, 3, {a: 1}, 5]arr1.forEach((item, index) => {    if (item.a) {        item.a += 1    } else {        item += 1    }})console.log(arr1)// 0:1// 1:2// 2:3// 3:{a: 2}// 4:5复制代码

forEach遍历出来的对象会被直接更改,原因是JS中对象传值引用传递,传递的是内存地址,修改后会改变内存地址对应储存的值。而非对象只是进行了值传递,函数中可以用这个值,但是无法修改。

**注意:**forEach很容易修改原始数组的值


map
let arr1 = [1, 2, 3, {a: 1}, 5]let arr2 = arr1.map((item, index) => {    let imap    if (item.a) {        imap = item.a + 1    } else {        imap = item + 1    }    return imap})console.log(arr1)// 0:1// 1:2// 2:3// 3:{a: 1}// 4:5console.log(arr2)// 0:1// 1:2// 2:3// 3:2// 4:5复制代码

map需要有一个返回值,并且有新数组来接收最终数据,一般情况下map不会改变原始数组


every
isBelowThreshold(currentValue) {  return currentValue < 40}let array1 = [1, 30, 39, 29, 10, 13]console.log(array1.every(isBelowThreshold)) // true复制代码

every会将数组中每一项作为参数,传递给指定函数,返回值均为true则最终结果为true,相当于&&


some
isBelowThreshold(currentValue) {  return currentValue > 39}let array1 = [1, 30, 39, 29, 10, 13]console.log(array1.some(isBelowThreshold)) // true复制代码

every会将数组中每一项作为参数,传递给指定函数,返回值有一项为true则最终结果为true,相当于||


filter
isBelowThreshold (currentValue) {    return currentValue > 20},learnArray () {    let array1 = [1, 30, 39, 29, 10, 13]    console.log(array1.filter(this.isBelowThreshold)) // [30, 39, 29]}复制代码

filte同样会建数组中每一项作为参数,传递给函数进行过滤


reduce
getSum (total, num) {    return Math.round(total) + Math.round(num)},learnArray () {    let numbers = [15.5, 2.3, 1.1, 4.7]    console.log(numbers.reduce(this.getSum)) // 24}复制代码

reduce可以看做是一个累加器,从做开始依次执行,值得注意的是第一次执行是total作为初始值,之后执行total即使上一次累加的结果

concat() 方法用于连接两个或多个数组。
let arr1 = [1, 3, 4, 5]let arr2 = ['11', '1']let arr3 = [{ a: 1 }, { b: 2 }]let all = arr1.concat(arr2).concat(arr3)console.log(all) // [1, 3, 4, 5, "11", "1", {…}, {…}]复制代码
concat()方法,不会改变原数组本身

join(separator)把数组中每一项提取出来并用指定字符分割组成字符串
let arr1 = [1, 3, 4, 5, [1, 2, 3]]let arr2 = ['11', '1']let arr3 = [{ a: 1 }, { b: 2 }]let all = arr1.concat(arr2).concat(arr3)let str = all.join('v')console.log(str) // 1v3v4v5v1,2,3v11v1v[object Object]v[object Object]复制代码

separator为join方法暴露的参数,默认为','。**注意:**join可以提取String和Number但是无法解析对象中的数据


pop()删除数组最后一项,并返回被删除项,如果数组长度为0,则返回undefined
let arr1 = [0, 1, 2, 3, 4]let str = arr1.pop()console.log(str)	// 4console.log(arr1)	// [0, 1, 2, 3]复制代码

**注意:**pop()会改变源数组


push()方法可向数组的末尾添加一个或多个元素,并返回新的长度
let arr1 = [0, 1, 2, 3, 4]let str = arr1.push([5, 6])console.log(str)	// 6console.log(arr1) // [0, 1, 2, 3, 4, Array(2)]复制代码

**注意:**push()后向数组末尾添加指定数据,无论他什么类型,即使是NaN也会切只会占据数组中一个位置


reverse()颠倒数组中元素位置
let arr1 = [0, 1, 2, 3, 4]let str = arr1.reverse()console.log(str)	// [4, 3, 2, 1, 0]console.log(arr1)	// [4, 3, 2, 1, 0]复制代码

**注意:**此操作会改变源数组


shift()删除数组第一个元素,并返回被删除元素
let arr1 = [0, 1, 2, 3, 4]let str = arr1.shift()console.log(str)	// 0console.log(arr1)	// [1, 2, 3, 4]复制代码

**注意:**此操作会改变源数组


slice(start, end)从已有数组中选定一个范围组成子数组
let arr1 = [0, 1, 2, 3, 4]let arr2 = arr1.slice(1, 3)let arr3 = arr1.slice(-1)let arr4 = arr1.slice(1, -3)console.log(arr1)	// [0, 1, 2, 3, 4]console.log(arr2)	// [1, 2]console.log(arr3)	// [4]console.log(arr4)	// [1]复制代码

注意: start为必填项,确定开始位置,正数为顺序查询,负数为倒序查询;end为选填项,确定结束位置,默认为至最后一项


sort(sortby)对数组进行排序
**普通数组**sortNumber (a, b) {    return a - b},learnArray () {    let arr1 = ['10', '131', '234', '111', '20', '002', '0071']    console.log(arr1.sort())	// ["002", "0071", "10", "111", "131", "20", "234"]    console.log(arr1.sort(this.sortNumber))	// ["002", "10", "20", "0071", "111", "131", "234"]}**数组中的对象未处理前无法排序**learnArray () {    let arr = []    for (let i = 0; i < 5; i++) {        arr.push({i: i * Math.random()})        console.log(arr[i], arr[i].length)    }    console.log(arr.sort())    // 0:{i: 0}    // 1:{i: 0.16355624558752946}    // 2:{i: 1.7387739842785384}    // 3:{i: 0.3757190308241345}    // 4:{i: 3.160518025347579}}**经过特殊处理后的数组**sortNumber (a, b) {    let obj1 = a['i']    let obj2 = b['i']    return obj2 - obj1},learnArray () {    let arr = []    for (let i = 0; i < 5; i++) {        arr.push({i: i * Math.random()})        console.log(arr[i], arr[i].length)    }    console.log(arr.sort())    // 0:{i: 3.8106310267596397}    // 1:{i: 1.3285710809611437}    // 2:{i: 1.0776123310362173}    // 3:{i: 0.9429327310688747}    // 4:{i: 0}    console.log(arr.sort(this.sortNumber))    // 0:{i: 3.8106310267596397}    // 1:{i: 1.3285710809611437}    // 2:{i: 1.0776123310362173}    // 3:{i: 0.9429327310688747}    // 4:{i: 0}}复制代码

**注意:**sort()接受一个函数作为排序条件,默认按照字母顺序排列,函数的返回值应该是一个比较的结果,正数(正序)、负数(倒序)、或NAN(走默认排序),比较对象应该为由数字、字母任意组成的字符串,如果为sort传递了排序条件,默认排序会继承


splice(index,howmany,item1,.....,itemX)从数组中添加/删除元素
let arr = []let arr1 = arr.splice(0, 0, 1)console.log(arr)		// [1]console.log(arr1)		// []复制代码

index为起始位置,howmany为要删除项目数量,可以为0,item要添加的元素,splice方法会返回被删除的元素,并会改变原数组


toString将数组转换为对象并返回

结果与没有参数的join()方法一致,不会改变源数组


unshift在数组开头添加一个元素,并返回新长度

unshift会改变源数组,可以通过arr.unshift()拿到arr的长度


forEach
let arr1 = [1, 2, 3, {a: 1}, 5]arr1.forEach((item, index) => {    if (item.a) {        item.a += 1    } else {        item += 1    }})console.log(arr1)// 0:1// 1:2// 2:3// 3:{a: 2}// 4:5复制代码

forEach遍历出来的对象会被直接更改,原因是JS中对象传值引用传递,传递的是内存地址,修改后会改变内存地址对应储存的值。而非对象只是进行了值传递,函数中可以用这个值,但是无法修改。

**注意:**forEach很容易修改原始数组的值


map
let arr1 = [1, 2, 3, {a: 1}, 5]let arr2 = arr1.map((item, index) => {    let imap    if (item.a) {        imap = item.a + 1    } else {        imap = item + 1    }    return imap})console.log(arr1)// 0:1// 1:2// 2:3// 3:{a: 1}// 4:5console.log(arr2)// 0:1// 1:2// 2:3// 3:2// 4:5复制代码

map需要有一个返回值,并且有新数组来接收最终数据,一般情况下map不会改变原始数组


every
isBelowThreshold(currentValue) {  return currentValue < 40}let array1 = [1, 30, 39, 29, 10, 13]console.log(array1.every(isBelowThreshold)) // true复制代码

every会将数组中每一项作为参数,传递给指定函数,返回值均为true则最终结果为true,相当于&&


some
isBelowThreshold(currentValue) {  return currentValue > 39}let array1 = [1, 30, 39, 29, 10, 13]console.log(array1.some(isBelowThreshold)) // true复制代码

every会将数组中每一项作为参数,传递给指定函数,返回值有一项为true则最终结果为true,相当于||


filter
isBelowThreshold (currentValue) {    return currentValue > 20},learnArray () {    let array1 = [1, 30, 39, 29, 10, 13]    console.log(array1.filter(this.isBelowThreshold)) // [30, 39, 29]}复制代码

filte同样会建数组中每一项作为参数,传递给函数进行过滤


reduce
getSum (total, num) {    return Math.round(total) + Math.round(num)},learnArray () {    let numbers = [15.5, 2.3, 1.1, 4.7]    console.log(numbers.reduce(this.getSum)) // 24}复制代码

reduce可以看做是一个累加器,从做开始依次执行,值得注意的是如果不指定初始值第一次执行是total作为初始值也就是数组的第一个元素,之后执行total即使上一次累加的结果

另:reduce接收两个参数第一个为回调函数,第二个是初始值,也就是这里的total它非必传


实践应用
let old = [    {        id: 1,        name: 'css',        type: 'html'    },    {        id: 3,        name: 'javacript',        type: 'code'    },    {        id: 5,        name: 'css',        type: 'html'    }]复制代码

有一个数组,期望把相同name的对象合并,并且把对应的id放到一个数组

方法一、

let arr = []old.forEach((item) => {    let str = JSON.stringify(old)    if (str.indexOf(item.type) === -1) {        let obj = {            id: [item.id],            name: item.name,            type: item.type        }        arr.push(obj)    } else {        arr.forEach((items) => {            if (items.type === item.type) items.id.push(item.id)        })    }})复制代码

需要n^2次的循环,不推荐

方法二、

let isEqual = (a, b) => a.name === b.name && b.type === b.type // 判断条件let create = e => {	// 创建新对象    e.id = [e.id]    return e}let getNew = old => old.reduce((acc, cur) => {    let hasItem = acc.some(e => {    let temp = isEqual(e, cur)    if (temp) e.id.push(cur.id)    return temp})if (!hasItem) acc.push(create(cur))    return acc}, [])复制代码

循环次数减少了一半,推荐

转载地址:http://ynntx.baihongyu.com/

你可能感兴趣的文章
lodash速览:集合方法(二)
查看>>
Serverless+SCF=打倒服务器,解放程序员
查看>>
Java中获取类名的3种方法!
查看>>
React Native 屏幕适配(炒鸡简单的方法)
查看>>
Mac High Sierra版本中“已损毁,打不开。您应该将它移到废纸篓”问题的解决办法...
查看>>
关于 nginx 前端知道这些就够了
查看>>
Golang Gin实践 连载十二 优化配置结构及实现图片上传
查看>>
jCasbin:支持MAC、RBAC、ABAC多种模型的Java权限管理框架
查看>>
多线程基础必要知识点!看了学习多线程事半功倍
查看>>
laravel 内容理解和摘要
查看>>
订阅号页面偷取微信用户信息(unionId),-_-
查看>>
PHP SPL 笔记
查看>>
HTML、CSS笔记
查看>>
让前端攻城师独立于后端进行开发: Mock.js
查看>>
golang通用连接池的实现
查看>>
zookeeper和etcd有状态服务部署实践
查看>>
从koa-session中间件源码学习cookie与session
查看>>
事件处理---事件等级模型,捕获,冒泡,默认事件。
查看>>
ERP物理机迁移至阿里云实践
查看>>
30-seconds-code——string
查看>>