JavaScript数组

64 阅读4分钟

1. 数组的创建

  • 数组的结构

    • 一种有序的集合,里面的元素是按照某一个顺序来排列的,这个有序的集合,可以通过索引来获取到它,这个结构就是数组(Array)
  • 数组是一种特殊的对象类型,可以通过 [] 来创建一个数组
  • 创建数组
    • []
    • new Array()
      // 1.创建数组的方式
      var names = ["john", "kobe", "james", "curry"]
      
      var product1 = { name: "苹果", price: 10 }
      var products = [
        { name: "鼠标", price: 98 },
        { name: "键盘", price: 100 },
        { name: "西瓜", price: 20 },
        product1
      ]
      
      // 2.创建方式二: 类Array
      var arr1 = new Array()
      var arr2 = new Array("abc", "cba", "nba") // ["abc", "cba", "nba"]
      console.log(arr1, arr2)
      
      // 传入了一个数字, 它默认会当成要创建一个对应长度的数组
      var arr3 = new Array(5) // [empty*5]
      console.log(arr3, arr3[0])
      var arr4 = [5]
      
      // 3.通过索引访问元素
      console.log(names[0]) // 第一个元素
      console.log(names[names.length-1]) // 最后一个元素
      
  • 数组基本操作
    • 获取元素
      • [0]
      • at(0)
        • 如果 i >= 0,则与 arr[i] 完全相同。
        • 对于 i 为负数的情况,它则从数组的尾部向前数
    • 修改元素
      • arr[0] = "abc"
    • 新增/删除
      var names = ["abc", "cba", "nba"]
      
      // 1.访问数组中的元素
      console.log(names[0])
      console.log(names.at(0))
      
      console.log(names[-1])
      console.log(names.at(-1))
      
      // 2.修改数组中的元素
      // names[0] = "why"
      // console.log(names)
      
      // 3.新增数组中的元素(了解)
      // names[3] = "kobe"
      // names[10] = "james"
      // console.log(names)
      
      // 4.删除数组中的元素(了解)
      // delete names[1]
      // console.log(names)
      // console.log(names[1])
      

2. 新增/删除/替换元素

  • 尾部:

    • push 在末端添加元素
    • pop 从末端取出一个元素
  • 首部

    • shift 取出队列首端的一个元素,整个数组元素向前前移动
    • unshift 在首端添加元素,整个其他数组元素向后移动
  • 注意:push/pop 方法运行的比较快,而 shift/unshift 比较慢

  • splice:可以添加,删除和替换元素

    • 从start位置开始,处理数组中的元素

    • deleteCount:要删除元素的个数,如果为0或者负数表示不删除

    • item1, item2, ...:在添加元素时,需要添加的元素

  • 注意:这个方法会修改原数

    • start
    • deleteCount
      • 2
      • 0
    • item1/item2
    // var names = ["abc", "cba", "nba", "mba", "abcd"]
    
    // 1.在数组的尾部添加和删除元素
    // // push方法
    // names.push("john", "kobe")
    // console.log(names)
    // // pop方法
    // names.pop()
    // names.pop()
    // console.log(names)
    
    // // 2.在数组的头部添加和删除元素
    // // unshift方法
    // names.unshift("why", "kobe")
    // console.log(names)
    // // shift方法
    // names.shift()
    // console.log(names)
    
    // 3. 在任意位置添加/删除/替换元素
    var names = ["abc", "cba", "nba", "mba", "abcd"]
    // 参数一: start, 从什么位置开始操作元素
    // 参数二: deleteCount, 删除元素的个数
    
    // 3.1.删除元素
    // names.splice(1, 2)
    // console.log(names)
    
    // 3.2.新增元素
    // deleteCount: 0, 后面可以添加新的元素
    // names.splice(1, 0, "john", "kobe")
    // console.log(names)
    
    // 3.3.替换元素
    names.splice(1, 2, "john", "kobe", "james")
    console.log(names)
    

3 length属性

  • length属性用于获取数组的长度:

    • 修改数组的时候,length 属性会自动更新
  • length属性的另一个特点是它是可写

    • 如果手动增加一个大于默认length的数值,那么会增加数组的长度

    • 但是如果减少它,数组就会被截断

  • 清空数组最简单的方法就是:arr.length = 0;

    var names = ["abc", "cba", "nba", "mba"]
    
    // 获取数组的长度length
    console.log(names.length) // 4
    
    // // length属性可写的(扩容)
    names.length = 10
    console.log(names) // ['abc', 'cba', 'nba', 'mba', empty × 6]
    
    // // 设置的length小于原来的元素个数
    names.length = 0
    console.log(names) // []
    

4 数组的遍历

  • 普通的for
  • for in
  • for of
    var names = ["abc", "cba", "nba", "mba"]
    
    // 1. 普通的for循环
    for (var i = 0; i < names.length; i++) {
      console.log(names[i])
    }
    
    // 2. for..in
    for (var index in names) {
      console.log(index, names[index])
    }
    
    // 3. for..of
    for (var item of names) {
      console.log(item)
    }
    

5. 数组方法-slice-concat-join

  • arr.slice() :用于对数组进行截取(类似于字符串的slice方法)

    • 包含begin元素,但是不包含end元素
  • arr.concat() :创建一个新数组,其中包含来自于其他数组和其他项的值

  • arr.join() : 将一个数组的所有元素连接成一个字符串并返回这个字符串

    var names = ["abc", "cba", "nba", "mba", "kobe"]
    
    // 1.slice方法: 不会修改原数组
    // splice有区别: splice修改原有的数组
    // start 从什么位置开始
    // end 结束位置, 不包含end本身
    var newNames = names.slice(2, 4)
    console.log(newNames) // ["nba", "mba"]
    
    // 2.concat方法: 将多个数组拼接在一起
    var names1 = ["abc", "cba"]
    var names2 = ["nba", "mba"]
    var names3 = ["john", "kobe"]
    var newNames2 = names1.concat(names2, names3)
    console.log(newNames2)
    
    // 3.join方法: 字符串split
    console.log(names.join("-"))
    

6. 数组中查找某一个元素

  • arr.indexOf() :查找某个元素的索引

    • 从fromIndex开始查找,如果找到返回对应的索引,没有找到返回-1

    • 也有对应的从最后位置开始查找的 lastIndexOf() 方法

  • arr.includes() :判断数组是否包含某个元素

    • 从索引 from 开始搜索 item,如果找到则返回 true(如果没找到,则返回 false)
  • find() 和 findIndex() 直接查找元素或者元素的索引(ES6之后新增的语法),找到返回查找元素或者元素的索引,否则返回undefined或-1

    // 1.数组中存放的是原始类型
    var names = ["abc", "cba", "nba", "mba"]
    
    // 1.1. indexOf
    // 可以找到, 返回对应的索引
    // 没有找到, 返回-1
    // console.log(names.indexOf("nbb")) // -1
    
    // includes
    // console.log(names.includes("nba"))
    
    // findIndex: 查找元素的索引
    var findIndex = names.findIndex(function(item, index, arr) {
      return item === "nba"
    })
    // var findIndex = names.findIndex(item => item === "nba")
    console.log(findIndex) // 2
    
    // 2.数组中存放的是对象类型
    var students = [
      { id: 100, name: "john", age: 21 },
      { id: 101, name: "kobe", age: 30 },
      { id: 102, name: "james", age: 25 },
      { id: 103, name: "curry", age: 22 }
    ]
    
    // 查找的是id为101的学生信息
    // 2.1. 自己写一个for循环
    // var stu = null
    // for (var i = 0; i < students.length; i++) {
    //   if (students[i].id === 101) {
    //     stu = students[i]
    //     break
    //   }
    // }
    
    // // 判断上面的算法有没有找到对应的学生
    // if (stu) {
    //   console.log("找到了对应的101学生", stu)
    // } else {
    //   console.log("没有找到对应的101学生")
    // }
    
    // 2.2. find方法: 高阶函数
    var students = [
      { id: 100, name: "john", age: 21 },
      { id: 101, name: "kobe", age: 30 },
      { id: 102, name: "james", age: 25 },
      { id: 103, name: "curry", age: 22 }
    ]
    
    var stu = students.find(function(item) {
      if (item.id === 101) return true
    })
    console.log(stu)
    
  • 实现 forEach

    var names = ["abc", "cba", "nba"]
    
    // forEach函数: 可以遍历数组
    // for (var i = 0; i < names.length; i++) {
    //   console.log(names[i])
    // }
    
    // 1.myForEach版本一
    // function myForEach(fn) {
    //   for (var i = 0; i < names.length; i++) {
    //     fn(names[i], i, names)
    //   }
    // }
    
    // myForEach(function(item, index, names) {
    //   console.log("-------", item, index, names)
    // })
    
    // 2.myForEach版本二
    // function myForEach(fn, arr) {
    //   for (var i = 0; i < arr.length; i++) {
    //     fn(arr[i], i, arr)
    //   }
    // }
    
    // myForEach(function(item, index, names) {
    //   console.log("-------", item, index, names)
    // }, names)
    
    // myForEach(function(item, index, names) {
    //   console.log("-------", item, index, names)
    // }, [123, 321, 111, 222])
    
    
    // 3.myForEach版本三
    // names.myForEach = function(fn) {
    //   for (var i = 0; i < this.length; i++) {
    //     fn(this[i], i, this)
    //   }
    // }
    
    // names.myForEach(function(item, index, names) {
    //   console.log("-------", item, index, names)
    // })
    
    // names.forEach(function(item, index, names) {
    //   console.log("-------", item, index, names)
    // })
    
    
    // 4.myForEach版本四
    Array.prototype.myForEach = function(fn, thisArgs) {
      for (var i = 0; i < this.length; i++) {
        fn(this[i], i, this)
      }
    }
    
    // names.myForEach(function(item, index, names) {
    //   console.log("------", item, index, names)
    // })
    
    // var students = [
    //   { id: 100, name: "john", age: 21 },
    //   { id: 101, name: "kobe", age: 30 },
    //   { id: 102, name: "james", age: 25 },
    //   { id: 103, name: "curry", age: 22 }
    // ]
    
    // students.myForEach(function(item, index, stus) {
    //   console.log("++++++", item, index, stus)
    // })
    
  • 实现 find

    // 1.原始类型的查找
    var names = ["abc", "cba", "nba", "mba"]
    
    // 原生find方法
    var findName = names.find(function(item, index, arr) {
      console.log(item, index, arr)
      return item === "nba"
    })
    console.log(findName)
    
    // 2.数组中对象类型的查找
    var students = [
      { id: 100, name: "john", age: 21 },
      { id: 101, name: "kobe", age: 30 },
      { id: 102, name: "james", age: 25 },
      { id: 103, name: "curry", age: 22 }
    ]
    
    // var findStu = students.find(function(item) {
    //   return item.id === 101
    // })
    // console.log(findStu)
    
    // 3.自己实现myFind
    Array.prototype.myFind = function(fn) {
      // var item = undefined
      for (var i = 0; i < this.length; i++) {
        var isFlag = fn(this[i], i, this)
        if (isFlag) {
          // item = this[i]
          // break
          return this[i]
        }
      }
      // return item
    }
    
    var findStu = students.myFind(function(item, index, arr) {
      console.log(item)
      return item.id === 101
    })
    console.log(findStu) // {id: 101, name: 'kobe', age: 30}
    

7. sort-reverse

  • arr.sort([compareFunction])也是一个高阶函数,用于对数组进行排序,并且生成一个排序后的新数组

    • 如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 前面
    • 如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变
    • 如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 前面
    • 也就是说,谁小谁排在前面
  • reverse() 方法将数组中元素的位置颠倒,并返回该数组

    var nums = [20, 4, 10, 15, 100, 88]
    
    // sort: 排序
    nums.sort(function(item1, item2) {
      // item1和item2进行比较
      // 返回是 整数
      // 谁小谁在前
      // return item1 - item2
      return item2 - item1
    })
    
    console.log(nums) // [100, 88, 20, 15, 10, 4]
    console.log(nums.reverse()) // [4, 10, 15, 20, 88, 100]
    
    
    // 复杂类型的排序
    var students = [
      { id: 100, name: "john", age: 21 },
      { id: 101, name: "kobe", age: 30 },
      { id: 102, name: "james", age: 25 },
      { id: 103, name: "curry", age: 22 }
    ]
    
    students.sort(function(item1, item2) {
      return item1.age - item2.age
    })
    console.log(students)
    /*
        [{id: 100, name: 'john', age: 21}
        {id: 103, name: 'curry', age: 22}
        {id: 102, name: 'james', age: 25}
        {id: 101, name: 'kobe', age: 30}]
    */
    

8. 其他高阶函数

  • arr.forEach()

    • 遍历数组,并且让数组中每一个元素都执行一次对应的方法
  • arr.map()

    • 创建一个新数组

    • 这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成

  • arr.filter()

    • 创建一个新数组

    • 新数组中只包含每个元素调用函数返回为true的元素

  • arr.reduce()

    • 用于计算数组中所有元素的总和

    • 对数组中的每个元素按序执行一个由您提供的 reducer 函数

    • 每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值

    // 1.forEach函数
    var names = ["abc", "cba", "nba", "mba"]
    
    // 三种方式, 新增一种方式
    names.forEach(function(item) {
      console.log(item, this)
    }, { name: "kobe" })
    
    // 2.filter函数: 过滤
    // var nums = [11, 20, 55, 100, 88, 32]
    // 2.1. for循环实现
    // var newNums = []
    // for (var item of nums) {
    //   if (item % 2 === 0) {
    //     newNums.push(item)
    //   }
    // }
    // 2.2. filter使用
    // var newNums = nums.filter(function(item) {
    //   return item % 2 === 0
    // })
    // console.log(newNums)
    
    
    // 3.map函数: 映射
    // var nums = [11, 20, 55, 100, 88, 32]
    // var newNums = nums.map(function(item) {
    //   return item * item
    // })
    // console.log(newNums)
    
    // reduce 方法
    var nums = [11, 20, 55, 100, 88, 32]
    // var result = 0
    // for (var item of nums) {
    //   result += item
    // }
    // console.log(result)
    // 第一次执行: preValue->0 item->11
    // 第二次执行: preValue->11 item->20
    // 第三次执行: preValue->31 item->55
    // 第四次执行: preValue->86 item->100
    // 第五次执行: preValue->186 item->88
    // 第六次执行: preValue->274 item->32
    // 最后一次执行的时候 preValue + item, 它会作为reduce的返回值
    
    // initialValue: 初始化值, 第一次执行的时候, 对应的preValue
    // 如果initialValue没有传呢?会跳过上面的第一次执行
    var result = nums.reduce(function(preValue, item) {
      console.log(`preValue:${preValue} item:${item}`)
      return preValue + item
    }, 0)
    console.log(result)
    
    var nums = [11, 20, 55, 100, 88, 32]
    
    // 过滤所有的偶数, 映射所有偶数的平方, 并且计算他们的和
    var total = nums.filter(function(item) {
      return item % 2 === 0
    }).map(function(item) {
      return item * item
    }).reduce(function(preValue, item) {
      return preValue + item
    }, 0)
    console.log(total)
    
    var total = nums.filter(item => item % 2 === 0)
                    .map(item => item * item)
                    .reduce((preValue, item) => preValue + item, 0)
    console.log(total)