数组数据类型以及常用方法

133 阅读14分钟

数组数据类型

  • 什么是数组
    • 数组字面意思就是存放数字的一个组合, 但这么说太过于片面, 更完善的说法应该是 数组是存放一些数据的集合
    • 简单来说我们把数据放到一个盒子中, 这个盒子就是数组, 注意数字内的数据是有顺序的
    • 总结:数组是存放一些数据的集合也是引用数据类型(复杂数据类型)
    • 目前属于复杂数据类型的是:数据/对象/函数
var arr = [1, 2, 3, "qwe", "abc", true, false, undefined, null];
// 我们把一堆数据存放到一个盒子中, 这就叫做数组 对应我们上述的 数组是存放一些数据的集合
  • 数组和对象将来如何选择?
    • 示例:商品的详情存放到某一个对象中, 比如: 商品名, 商品价格, 商品折扣, 商品描述.... 商品列表假设有 100个商品, 那么你就有100个商品详情, 按照上述的封装那么你有100个对象 我们可以将 这 100个 对象, 存放到某一个数组中, 进行维护管理

一、创建数组数据类型

数组内部是存放一些数据的, 数据的类型没有限制 但是在开发的时候一般需要将一个数组内的数据类型限制为一个 比如: 纯字符串数组, 纯数字数组, 纯对象数组 注意 函数不能够写在数组里面

1.使用字面量的方式创建数组(使用场景最多方式)

var arr = [];  // 创建一个空数组
console.log(arr)  //[]

var arr1 = [1, 2, 3];  // 创建一个有内容的数组
console.log(arr1)  //[1,2,3]
  • 内置构造函数创建数组
var arr = new Array() // 创建一个空数组
console.log(arr)  //[]

var arr1 = new Array(10) // 创建一个有长度为10的数组
console.log(arr1)  //(10) [empy*10]

var arr2 = nee Array(1, 2, 3) // 创建一个有内容的数组
console.log(arr2)  //[1,2,3]

二.数组的 length (长度)属性

  • length 就是长度的意思, 代表数组内有多少个成员(数据)
  • 数组的长度并不固定,取决于数组内部有多少个元素
  • 查看方式:
    • 1、打印数据,在控制台展开数组,找到最后的length
    • 2、打印 数组名.length
  • 当数组的长度 === 0 ,代表当前数组为空数组
  • 当数组为空数组的时候,做某些操作
var arr = [1, 2, 3];
console.log(arr.length); // 3
console.log(arr); // [1,2,3]

var arr1 = [4, 5];
console.log(arr1.length); // 2
console.log(arr1); // [4,5]

if(arr.length === 0){   //[]
`xxxxxxxx 
}                

三.数组的 索引(下标) 概念

  • 索引也叫做下标, 就是指一个数据在这个数组内排列在第几个位置上
    • 注意: 在所有的语言中, 索引(下标)都是从 0 开始的,永远是0 1 2 3 4 ...但是下标对应的内容不是固定的
   var arr=[1,2,3,4,5]
    //下标: 0 1 2 3 4
    
    console.log(arr)
    console.log(arr[0])//会得到当前数组下标0这个位置上的值--1
    
    //通过数组的下标,我们也可以修改数组中某一个元素的内容
    arr[2] = '新数据'
    
    console.log('修改后的数组:',arr)//[1,2,'新数据',4,5]
var arr = ["hello", "world"];
// 在这个数组中, 第一个数据(元素)是 'hello', 那么它的下标就是 0, 后续的 'world', 下标为1
// 想要获取数组中某一个位置上的数据(元素), 可以直接 数组名[下标]

console.log(arr[0], arr[1]);

四.数组遍历

遍历数组就是想办法拿到数组的每一个元素, 通常我们可以通过下标获取到元素的某一项, 所以我们只需要想办法拿到数组的所有下标即可

1.需求是拿到数组中各个位置的值

    var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        for (var i = 0; i < arr.length; i++) {
            console.log(arr[i])
        }

数组基本操作案例

(1).找出数组中的最大值

    var arr = [34, 65, 76, 50, 12, 24]
        var max = arr[0]
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i]
            }
        }
        console.log(`最大值是${max}`)

(2).计算数组中所有内容相加的和

    var arr = [34, 65, 76, 50, 12, 24]
        var sum = 0
        for (var i = 0; i < arr.length; i++) {
            sum += arr[i]
        }
        console.log(`数组内容和为${sum}`)

(3).封装一个函数,名为includes

  • 功能:传入一个数组和数字,判断这个数组中是否包含这个数字;包含返回true,否则false
    function includes(arr, num) {
            for (var i = 0; i < arr.length; i++) {
                if (arr[i] === num) {
                    return true
                }
            }
            return false
        }
        var res = includes([12, 23, 34, 45, 56, 67], 23)
        console.log(res)

(4).封装一个函数,名为indexOf

  • 功能:传入一个数组和数字,判断这个数组中是否包含这个数字,包含返回这个数字的下标(从左到右第一个)否则返回-1
   function indexOf(arr, num) {
            for (var i = 0; i < arr.length; i++) {
                if (arr[i] === num) {
                    return i
                }
            }
            return -1
        }

        var res = indexOf([12, 67, 23, 34, 45, 56, 67], 675)
        console.log(res)

(5).封装一个函数,名为indexOf

    • 功能:书写一个函数 LastIndexof 功能和 indexof 相同,但是查的顺序为 从右到左.
   function lastIndexOf(arr, num) {
            for (var i = arr.length - 1; i >= 0; i--) {
                if (arr[i] === num) {
                    return i
                }
            }
            return -1
        }

        var res = lastIndexOf([12, 67, 23, 34, 45, 56, 12, 67], 67)
        console.log(res)

五.冒泡排序

var arr = [9, 6, 3, 1, 4, 7, 8, 2, 5];
console.log("原始数组: ", arr);
for (var i = 0; i < arr.length - 1; i++) {
    for (var j = 0; j < arr.length - 1 - i; j++) {
        if (arr[j] > arr[j + 1]) {
            var temp = arr[j];
            arr[j] = arr[j + 1];
            arr[j + 1] = temp;
        }
    }
}
console.log("交换后的数组: ", arr);

1.基础班

    var arr = [9, 8, 7, 6, 5, 4, 3, 2, 1]
    // 冒泡排序 (基础版, 没有优化)
        for (var j = 0; j < arr.length; j++) {
            for (var i = 0; i < arr.length; i++) {
                if (arr[i] > arr[i + 1]) {
                    var temp = arr[i]
                    arr[i] = arr[i + 1]
                    arr[i + 1] = temp
                }
            }
            console.log('第 ', j + 1, ' 轮冒泡排序后: ', arr)
        }

2.优化版本

    var arr = [9, 8, 7, 6, 5, 4, 3, 2, 1]
     for (var i = 0; i < arr.length - 1; i++) {
            for (var j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    var temp = arr[j]
                    arr[j] = arr[j + 1]
                    arr[j + 1] = temp
                }
            }
        }
        console.log(arr)

3.整个优化过程

    /**
         *  优化 1: 外层循环可以减少一次
         * 
         *      一共 9 个数字, 所以需要执行 9 次 冒泡
         * 
         *      但是前 8 次执行完毕后, 就剩下一个位置和一个数字 没有验证了
         * 
         *      所以没必要执行最后一次了, 因为没有多的位置
        */
        // for (var j = 0; j < arr.length - 1; j++) {
        //     for (var i = 0; i < arr.length; i++) {
        //         if (arr[i] > arr[i + 1]) {
        //             var temp = arr[i]
        //             arr[i] = arr[i + 1]
        //             arr[i + 1] = temp
        //         }
        //     }
        // }
        // console.log('冒泡排序后: ', arr)
        
        
        
        //优化2:内层循环 - 1
        // for (var j = 0; j < arr.length - 1; j++) {
        //     for (var i = 0; i < arr.length - 1; i++) {
        //         /**
        //          *  当前 数组 arr.length === 9
        //          * 
        //          *  那也就是说 i 最大 为 8
        //          * 
        //          *  所以最后一轮循环 i === 8
        //          * 
        //          *  判断的内容为 arr[i] > arr[i + 1]
        //          *              arr[8] > arr[9]
        //          * 
        //          *  所以最后一次 判断没有意义, 所以我们此时应该让 内层循环 - 1
        //         */
        //         if (arr[i] > arr[i + 1]) {
        //             var temp = arr[i]
        //             arr[i] = arr[i + 1]
        //             arr[i + 1] = temp
        //         }
        //     }
        // }
        // console.log('冒泡排序后: ', arr)


        // 优化 3, 去掉多余的无用对比
        // for (var j = 0; j < arr.length - 1; j++) {
        //     console.log('当前是第 ', j + 1, ' 次循环, 此时变量 j ===', j)
        //     for (var i = 0; i < arr.length - 1 - j; i++) {
        //         console.log('此时对比的是: ', arr[i], arr[i + 1])
        //         if (arr[i] > arr[i + 1]) {
        //             var temp = arr[i]
        //             arr[i] = arr[i + 1]
        //             arr[i + 1] = temp
        //         }
        //     }
        //     console.log('==========================================================')
        // }
        // console.log('冒泡排序后: ', arr)

六、选择排序

var arr = [9, 6, 3, 1, 4, 7, 8, 2, 5];
console.log("原始数组: ", arr);
for (var j = 0; j < arr.length; j++) {
    // 1. 假定数组中的第 0 个是最小数字的索引
    var minIndex = j;
    // 2. 遍历数组找到数组中最小的哪一项的下标将其替换之前记录的索引
    for (var i = j; i < arr.length; i++) {
        if (arr[i] < arr[minIndex]) {
            minIndex = i;
        }
    }
    // 3. 遍历结束, 找到最小的索引, 将两个位置的数据对换
    var temp = arr[j];
    arr[j] = arr[minIndex];
    arr[minIndex] = temp;
}
console.log("排序结束后: ", arr);

(1)优化版

    var arr = [76, 45, 65, 23, 12, 98]
        for (var i = 0; i < arr.length - 1; i++) {
            var minIndex = i
            for (var j = i + 1; j < arr.length; j++) {
                if (arr[minIndex] > arr[j]) {
                    minIndex = j
                }
            }
            var temp = arr[i]
            arr[i] = arr[minIndex]
            arr[minIndex] = temp
        }
        console.log(arr) 

(2)整个优化过程

       /**
         * 选择排序
        */
        var arr = [9, 3, 6, 2, 4, 1, 8, 5, 7]
        //         0  1  2  3  4  5  6  7  8


        /**
         *                  第几次循环      假设谁是最小值      和谁交换        内层循环从 ? 开始
         * 
         *      k === 0         1               0               0                   1
         *      k === 1         2               1               1                   2
         *      k === 2         3               2               2                   3
        */


        for (var k = 0; k < arr.length; k++) {
            // 1. 假设 k 是最小值的下标, 保存在 minIndex
            var minIndex = k
            // 2. 循环会帮我们找到真实最小值的下标, 并保存在变量 minIndex
            for (var i = k + 1; i < arr.length; i++) {
                if (arr[minIndex] > arr[i]) {
                    minIndex = i
                }
            }
            // 3. 交换 真实最小值(下标 minIndex) 和 假设最小值 (k) 的位置
            var temp = arr[k]
            arr[k] = arr[minIndex]
            arr[minIndex] = temp
        }

        console.log('排序后: ', arr)



        // 假设这是我们第 11111111111111111111111111111 轮 选择排序
        // 1. 假设 下标0 是最小的值
        // var minIndex = 0
        // // 2. 循环遍历数组, 找到真实最小的值对应的下标
        // for (var i = 1; i < arr.length; i++) {
        //     if (arr[minIndex] > arr[i]) {
        //         minIndex = i
        //     }
        // }
        // // 上述循环执行完毕后, 我们一定会得到最小值对应的下标
        // // console.log(minIndex)
        // // 3. 将 真实最小值(下标minIndex)和假设最小值(下标0)做一个交换
        // var temp = arr[0]
        // arr[0] = arr[minIndex]
        // arr[minIndex] = temp
        // console.log('第 11111111111111111111111111111 轮 选择排序后: ', arr)


        // // 假设这是我们第 22222222222222222222222222222222 轮 选择排序
        // // 1. 假设 下标1 是最小的值 (因为 第一轮结束后, 下标0 真的是最小值)
        // var minIndex = 1
        // // 2. 循环遍历数组, 找到真实最小的值对应的下标
        // for (var i = 2; i < arr.length; i++) {
        //     if (arr[minIndex] > arr[i]) {
        //         minIndex = i
        //     }
        // }
        // // 上述循环执行完毕后, 我们一定会得到最小值对应的下标
        // // console.log(minIndex)
        // // 3. 将 真实最小值(下标minIndex)和假设最小值(下标1)做一个交换
        // var temp = arr[1]
        // arr[1] = arr[minIndex]
        // arr[minIndex] = temp
        // console.log('第 22222222222222222222222222222222 轮 选择排序后: ', arr)

        // // 假设这是我们第 333333333333333333333333333333333333333 轮 选择排序
        // // 1. 假设 下标2 是最小的值 (因为 前两轮结束后, 下标0 和 下标1 真的是最小值)
        // var minIndex = 2
        // // 2. 循环遍历数组, 找到真实最小的值对应的下标
        // for (var i = 3; i < arr.length; i++) {
        //     if (arr[minIndex] > arr[i]) {
        //         minIndex = i
        //     }
        // }
        // // 上述循环执行完毕后, 我们一定会得到最小值对应的下标
        // // console.log(minIndex)
        // // 3. 将 真实最小值(下标minIndex)和假设最小值(下标2)做一个交换
        // var temp = arr[2]
        // arr[2] = arr[minIndex]
        // arr[minIndex] = temp
        // console.log('第 333333333333333333333333333333333333333 轮 选择排序后: ', arr)

数组常用方法

  1. push:
    • 语法:数组名.push(数据)
    • 作用:向数组末尾添加数据
    • 返回值:追加数据后,新数组的长度
        var arr = [1,2,3,4,5];
        console.log(arr.push(6));   //返回新数组长度  6
        console.log(arr);           //新数组         [1, 2, 3, 4, 5, 6]
  //函数实现
        var arr = [1,2,3];
        function push (arr,date){
            // 向数组末尾插入数据,下标为数组的长度
            //因为下标是从0开始的,所以数组下标最大是arr.length-1,
            // 下标为数组的长度就是一个undefined然后给赋值
            // 以上会实现push的向数组末尾添加数据
            arr[arr.length] = date  
            // 返回数组的长度
            return arr.length
        }
        console.log(push(arr,8))     // 返回新数组的长度4
        console.log(arr)             // 新数组  [1,2,3,8]

注意:在函数传参的过程中,如果实参的值是一个引用数据类型,然后在函数内部对这个形参做了一些修改,那么会影响到函数外边的原数据。

  1. pop:
    • 语法: 数组名.pop()
    • 作用: 删除数组最后一条数据
    • 返回值: 删除的数据
        var arr = [1,2,3]
        console.log(arr.pop());  // 返回新数组被删除的数据是3
        console.log(arr);          //新数组   [1,2]
 // 函数实现
        var arr = [1,2,3,4]
        function pop(pop_arr) {
            // 先将数组末尾的数据保存,用于删除返回出去
            var num = pop_arr[pop_arr.length - 1];   //把下标为2的值存起来
            // 删除写法一: 数组末尾最后一个数据 保留位置
            delete pop_arr[pop_arr.length - 1]     //把下标为2的值删除掉
            // 删除写法二: 不保留位置
            // pop_arr.length -= 1
            // 返回被删除的数据  
            return num
        }
        console.log(pop(arr));   //返回被删除的数据长度是4
        console.log('新数组:', arr)   //返回新数组  [1,2,3]
  1. unshift:
    • 语法:数组名.unshift(数据)
    • 作用:向数组开头添加数据
    • 返回值:添加数据后,新数组的长度
        var arr = [1,2,3,4,5];
        console.log(arr.unshift(0));   //返回新数组长度     6
        console.log(arr);           //新数组         [0, 1, 2, 3, 4, 5]
  • 1)自己封装一个unshift函数(原数组不变)
    //自己封装一个unshift函数
    var arr = [1, 2, 3]
    function unshift(unshift_arr,data) {
        //逻辑:1、创建一个新的数组,然后将这个数组开头放上我们执行要         //添加的数据在2、将原本数组后续的内容,放在新数组的后边
        
        //1、创建一个新的数组,然后将这个数组开头放上新加的数据
        var arr2 = [data]
        //2、将原本数组后续的内容,放在新数组的后边
        for(var i = 0; i < unshift_arr.length; i++){
            arr2[i+1] = unshift_arr[i]
        }
        return {
            arr:arr2,
            len:arr2.length
        }
    }
    var res = unshift(arr, 'newData')
    console.log(res)
    console.log(res.arr)
    console.log(res.len)
  • 2)自己封装一个unshift函数(原数组不变)
var arr = [1, 2, 3]
        console.log('原数组: ', arr)
        function unshift(unshift_arr, data) {
            // 1. 创建一个新的数组, 然后将这个数组开头放上我们执行要添加的数据
            var newArr = [data]

            // 2. 在将原本数组后续的内容, 放在新数组的后边
            for (var i = 0; i < unshift_arr.length; i++) {
                newArr[i + 1] = unshift_arr[i]
            }
            // console.log('函数内部得到一个我们想要的数组: ', newArr)
            // unshift_arr = newArr    // 这样写不对, 原因后续会详细讲解

            // 3. 遍历 我们想要得到的数组, 拿到每一项, 然后重新赋值给 unshift_arr
            for (var k = 0; k < newArr.length; k++) {
                unshift_arr[k] = newArr[k]
            }
            /**
             *  此时 只需要返回一个数组的最新长度即可
             *          返回 这两个数组哪一个都无所谓
             *  因为 经过 上述 三个步骤 此时两个数组 长得一模一样
             * 
             *  但是要注意, 只是长得一样, 完全不是一个数组
             * 
             *  就好比: 两个卧室装修的一模一样, 但两个房间不是同一个
            */
            // return unshift_arr.length
            return newArr.length
        }
        var res = unshift(arr, 'newData')
        console.log('函数执行完毕后的原数组: ', arr)
  1. shift:
    • 语法: 数组名.shift()
    • 作用: 删除数组第一条数据
    • 返回值: 删除的数据
        var arr = [1,2,3,4,5];
        console.log(arr.shift());     //返回删除的数据
        console.log(arr);             //新数组[2,3,4,5]
// 函数实现
        //自己封装一个shift函数
        //作用:删除数组第一个数据
        //返回值:被删除的数据
        var arr = [1, 2, 3]
        function shift(shift_arr) {
            //1、暂存数组首位的内容,将来要返回出去
            var temp = shift_arr[0]
            //2、遍历数组找到数组所有内容,删除首位的内容
            for (var i = 0; i < shift_arr.length; i++) {
                shift_arr[i] = shift_arr[i + 1]
            }
            /*经过上述循环后,数组中【0】的值已经被替换了,但最后            多了一个undefined,那么此时只需要删除数组末尾的值就            可*/
            shift_arr.length -= 1
            return temp
        }
        var res = shift(arr)
        console.log(res)
  1. reverse:
    • 语法: 数组名.reverse()
    • 作用: 反转数组
    • 返回值: 反转后的数组
    • 该方法能够改变原数组
       // reverse
        var res = arr.reverse()
        console.log(arr)//[500, 100, 400, 300, 200, 100]
        console.log(res)//[500, 100, 400, 300, 200, 100]
        // 函数实现
        //自己封装一个reverse函数
        //作用:反转数组
        //返回值:反转后的数组
        function reverse(arr) {
            //1、交换数组内部元素的位置
            for (var i = 0; i < arr.length / 2; i++) {
                var temp = arr[i]
                arr[i] = arr[arr.length - 1 - i]
                arr[arr.length - 1 - i] = temp
            }
            return arr
        }
        var res = reverse(arr)
        console.loh(res)
  1. sort:
    • 语法1: 数组名.sort()
    • 作用: 将数组内的数据,转换为 字符串,然后一位一位的对比
    • 语法2: 数组名.sort(function (a,b) {return a - b})
    • 作用: 会按照数字 从小到大排序 升序排序
    • 语法2: 数组名.sort(function (a,b) {return b - a})
    • 作用: 会按照数字 从小到大排序 降序排序
    • 作用:将数组进行排序
    • 返回值: 排列后的数组
    • 注意sort使用后能够修改原数组,

语法1

       //语法1
        var arr = [1, 2, 3, 4, 5, 100, 300, 401, 404, 500, 1001, 2023]
        console.log('原数组', arr)
        console.log('sort 的返回值', arr.sort())
        //[1, 100, 1001, 2, 2023, 3, 300, 4, 401, 404, 5, 500]
        console.log('sort方法后的数组', arr)

语法2

        //语法2
        var arr = [54, 65, 23, 1, 89]
        arr.sort(function (a, b) {
            return a - b
        })
        console.log(arr)//[1, 23, 54, 65, 89]

语法3

        //语法3
        var arr = [54, 65, 23, 1, 89]
        arr.sort(function (a, b) {
            return b - a
        })
        console.log(arr)//[89, 54, 54, 23, 1]
  1. splice:
    • 语法1: 数组名.splice(开始索引,多少个)
    • 语法2: 数组名.splice(开始索引,多少个,新数据1,新数据2...)
    • 开始索引:默认为0;多少个:默认为0;要插入的数据:默认是没有
    • 作用: 截取数组内容,删除数组中若干数据,并选择是否插入新的数据
    • 返回值: 以数组类型返回截取的数据
        // splice
        var arr = [1, 2, 3, 4, 5]

        //语法1
        arr.splice(0, 3) //从下标0开始,剪切3个
        console.log(arr) //[4,5]
        var res = arr.splic(0, 3)
        console.log('剪切到的内容:', res)// [1,2,3]
        console.log('剪切后的数组', arr) //[4,5]

        //语法2
        arr.splice(0, 3, '新的数据', true, undefined) //从下标0开始,剪切3个
        console.log(arr) //['新的数据',true,undefined,4,5]
        var res = arr.splic(0, 3, '新的数据', true, undefined)
        console.log('剪切到的内容:', res)// [1,2,3]
        console.log('剪切后的数组', arr) //[新的数据',true,undefined,4,5]

使用哪些方法会改变原数组以上七种!

不改变原数组

  1. indexOf:
    • 语法1: 数组名.indexOf(要检查的数据);
    • 语法2:数组名.indexOf(要检查的数据, 开始索引)
    • 作用: 按照从左到右的顺序,查找数组中是否包含这个数据
    • 返回值: 如果数组中找到该数据,则返回相应索引,如果没找到返回 -1
        var arr = [23,456,75,23,234,14,121,74,967,4,121]
        // indexOf
        console.log(indexOf(75,0));     //找到  返回对应下标
        console.log(indexOf(1,0));      //没找到  返回-1
        console.log(indexOf(23,0));     //从下标 0 开始查找  返回0
        console.log(indexOf(23,1));     //从下标 1 开始查找  返回3
// indexOf
        var arr = [1, 2, 3, 4, 1, 2, 3]
        //         0 1 2 3 4 5 6
        console.log(arr.indexOf(1))// 0
        console.log(arr.indexOf(100))//-1
        console.log(arr.indexOf(1, 3))//4
        console.log(arr.indexOf(1, 5))//-1
    
        console.log('arr:', arr)//不会改变原数组


         //手写一个indexOf函数实现功能
        var arr = [1, 2, 3, 4, 1, 2, 3]
        function indexOf(arr, num, b = 0) {
            for (var i = b; i < arr.length; i++) {
                if (num === arr[i]) {
                    return i
                }
            }
            return -1
        }
        var res = indexOf(arr, 2, 2)
        console.log(res)

补充数组塌陷(使用splice清空数组)

 // 用splice清空数组
        var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
        for (var i = 0; i < arr.length; i++) {
            arr.splice(i, 1)
            i--
        }
        // arr.splice(0, arr.length)
        console.log(arr)