ChapterVII -- 数组

225 阅读9分钟

创建数组

//1、let 数组名 = Array(数据1 ,数据2 ,数据3,....)
     var arr = Array('a', 'ab', 'abc');
     console.log(arr);
     console.log(arr[0]);//单独访问数组的数据
     console.log(arr[1]);
     console.log(arr[2]);
     console.log(arr.length);//输出数组的长度
//2、字面量
     var arr1 = [
         'a', 'ab', 'abc'];
     ['a', 'ab', 'abc'];
     /console.log(arr1 == arr);// 数组的toString
     // arr1.sort();
//数组的遍历
     for (let index = 0; index < arr1.length; index++) {
         const element = arr1[index];
         console.log(index);
         console.log(arr1);
     }
// 完全复制一个对象数组,使得新数组中的对象修改后不影响旧数组
    var numbers = [1, 2, 3, 4, 5];
    let [...copy] = numbers;
    copy.push(6); // 添加新项以证明不会修改原始数组

    console.log(copy);
    console.log(numbers);
    
    var [...iterator] = numbers;
    console.log(iterator === numbers); //复制一个一模一样的对象,但是地址不一样

    let numbers = [
        { name: 'zhangsan', age: 18, sex: '男' },
        { name: 'zhangsan', age: 18, sex: '男' },
        { name: 'zhangsan', age: 18, sex: '男' },
    ];

    console.log(numbers);

    let [...iterator] = numbers;//复制一个一模一样的对象,但是地址不一样
// Object.assign(目标对象,要复制的对象) 会把复制对象中的所有键值复制到目标对象中,然后返回目标对象,目标对象中本身存的键值对会保留
    iterator[0] = Object.assign({ name: 'zhangsan123', age: 18, sex: '男' });
    console.log(iterator);

    let iterator = [];
// Object.assign(目标对象,要复制的对象) 会把复制对象中的所有键值复制到目标对象中,然后返回目标对象,目标对象中本身存的键值对会保留
    Object.assign(iterator, numbers);
    iterator[0] = Object.assign({ name: 'admain123', age: 18, sex: '男' });
    console.log(iterator);
    
    var arr = [1, 3, 2, 5, 4]
    arr.sort(function (a, b) { return a - b });
    var arr1 = [1, 3, 2, 5, 4]
    console.log(arr == arr1);
    for (let index = 0; index < arr.length; index++) {
        const element = arr[index];
        if (arr[index] == arr.sort(function (a, b) { return a - b })) {
            console.log(true);
        } else {
            console.log(false);
        }
    }
    

    var arr = ['1','2','3','4','4'];
    console.log(arr.join(''));
    

数组的常用函数

    let arr = [1, 4, 6, 8, 3, 9, 5]
    console.log(arr);
    arr.push(12) //push 最后边添加一个数组元素
    
    console.log(arr);
    arr.unshift(22)//unshift 最前边添加一个数组元素
    
    console.log(arr);
    arr.pop() //pop 从尾部删除一个数组元素
    
    console.log(arr);
    arr.shift() //shift 从头部删除一个数组元素
    
    console.log(arr);
    arr.splice(1, 3) //从定位的位置删除指定长度的数据
    
    console.log(arr);
    let arr1 = arr.slice(1, 4)//数组元素的提取,从开始位置提取到结束位置,包头不包尾,把提取到的数据做为返回值返回,不影响原数组
    
    console.log(arr1);
    arr1.join('.')//链接的字符串,把数组元素用连接字符串链接返回
    
    console.log(arr1);
    let ar = arr.indexOf(9, 0)
    console.log(ar);//从左到右获取在数组中遇到的第一个符合条件的index,把索引号返回如果没有返
    回-1
    let ar1 = arr.lastIndexOf(5)
    console.log(ar1);//从右到左获取在数组中遇到的第一个符合条件的index,把索引号返回如果没有返回-1
    
    arr.sort(); //排序,默认升序
    console.log(arr);
    
    arr.sort(function (a, b) { return b - a })//当回调函数的返回值为 a-b 时升序 b-a 时降序
    console.log(arr);
    
//forEach :一直循环遍历数组元素,把每次循环到的值和索引号做为回调函数的参数,并执行回调函数
    let arr = ['a', 'b', 'c', 'd', 'e']
    arr.forEach((element, index, arr) => {
        console.log(element, index);
    })
    console.log('----------------------------------');
    for (let index = 0; index < arr.length; index++) {
        const element = arr[index];
        console.log(element, index);
    }
    console.log('----------------------------------');

    function fu(fun) {
        for (let index = 0; index < arr.length; index++) {
            const element = arr[index];
            fun(element, index)
        }
    }
    fu(function fu2(element, index) {
        console.log(element, index);
    })
//map : 遍历数组,跟foreach一样
    //区别 : map把回调函数每一次执行的返回值封装到一个数组中返回
    let arr1 = [
        { username: 'admin', password: 'admin123' },
        { username: 'admin', password: 'admin123' },
        { username: 'admin', password: 'admin123' }
    ]
    /* arr1.map((element, index) => {
        console.log(element, index);
    })

    //在对象里新增一个键值对,但是要求原数组不变
    let srult = arr1.map((element, index) => {
        element = { ...element }
        element.isShow = 'zhangsan'
        return element;
    })
    console.log(srult);
    console.log(arr1); */
    let arrs = arr1.filter((element, index) => {
        if (index == 2) {
            return 123;
        }
        console.log(element, index);
    })
    console.log(arrs);
    // 给每个对象里添加 isShow : index
    // 返回值是true 的放到新的数组里,其它的不要
    let arr4 = arr1.map((element, index) => {
        //element 代表数组里的元素 . isShow 添加新数组元素的属性名 = index 数组里的索引号 == 如果索引号等等于 2 时就取 true 分号前的第一个值 如果不是就取 fales
        element.isShow = index == 2 ? true : false;
        return element;
    }).filter((element) => {
        return element.isShow
    })
    console.log(arr1);
    console.log(arr4);
//some (回调函数)回调函数中只要有一次返回true ,some的结果是true ,一旦遇到true 则some停止执行并返回
    let arr2 = [
        { username: 'admin1', password: 'admin123', islies: true, id: 1006001, name: "轻奢纯棉刺绣水洗四件套", brief: "设计师原款,精致绣花", },
        { username: 'admin2', password: 'admin123', islies: true, id: 1006002, name: "轻奢纯棉刺绣水洗四件套", brief: "设计师原款,精致绣花", },
        { username: 'admin3', password: 'admin123', islies: true, id: 1006003, name: "轻奢纯棉刺绣水洗四件套", brief: "设计师原款,精致绣花", },
        { username: 'admin3', password: 'admin123', islies: true, id: 1006003, name: "轻奢纯棉刺绣水洗四件套", brief: "设计师原款,精致绣", }
    ]

    var result = false;

    //判断username是否存在数组里
    /* for (let index = 0; index < arr2.length; index++) {
        const element = arr2[index];
        if (element.username == username) {
            result = true;
            break;
        }
    }
    console.log(result);
     */
    console.log(arr2);
//some (回调函数)回调函数中只要有一次返回true ,some的结果是true ,一旦遇到true 则some停止执行并返回
    function fuu(arr2) {
        // 创建目标数组
        var asrr = [];
        // forEach 遍历旧数组
        arr2.forEach(element => {
            //索引号的默认为0
            var aarr = 0;
            // some 循环新数组判断索引号的上的属性是否已经存在
            var asrr1 = asrr.some((value, index) => {
                //每循环一次就把索引号赋值给 aarr,如果索引号上的属性(username)相同,那么它的值就会新增到相同的属性上
                aarr = index
                // 判断旧数组里的索引号上的属性名是否已经存在新数组里
                return element.username == value.username;
            });
            // 如果已经存在就把 id name brief 属性名放入新数组的 goodsList 属性里
            if (asrr1) {
                asrr[aarr].goodsList.push({
                    id: element.id,
                    name: element.name,
                    brief: element.brief
                })
                // 如果不存在就把旧数组里相对应的属性放入新数组里
            } else {
                asrr.push({
                    username: element.username,
                    password: element.password,
                    goodsList: [{
                        id: element.id,
                        name: element.name,
                        brief: element.brief
                    }]
                })
            }
        });
        return asrr;
    }
    console.log(fuu(arr2));
//every (回调函数)所有回调都返回true 时,结果才是true ,只要有一个是false,返回的结果就是false
    console.log(arr.every((element, index) => {
        return !element.islies;
    }));
    //判断一个数组中是否都是数字 
    var num1 = false;
    var num = [1, 2, 3, 4, 5, 6, 7]
    console.log(num.every((element, index) => {
        return typeof (element) == 'number';
    }));
    //判断一个数组中是否都是数字 ,如果是,在判断是否含有偶数
// reduce (回调函数) :迭带
    /* 数组名.reduce(function(pre(前一次回调结果),element(当前循环到的值),index(当前循环到的索引)){
        console.log(arguments(获取所有参数列表));
        console.log(element);
    }) */
    console.log(num.reduce((pre, element, index) => {
        return pre + element;
    }));

    //求出数组的总和
    function test03(arr2) {
        return arr2.reduce((pre, element, index) => {
            return pre + element;
        }, 0);
    }
    console.log(test03([1, 2, 3]));
    

练习

//给定任意字符串,去掉重复的字符,只保留一个,例如:"aabbcc"去重后为"abc"
        var strs = 'aabbcc';
        function unique(strs) {
            var newStr = '';
            for (let i = 0; i < strs.length; i++) {
                if (newStr.indexOf(strs[i]) === -1) {
                    newStr += strs[i];
                }
            }
            return newStr;
        }
        console.log(unique(strs));
//给定任意字符串str和任意字符s,统计s在str中出现的次数
    let ori = 'sjsjsksbsssjvsj'
    /*  //使用split 把字符串转成数组
     var ori1 = ori.split('')
     var index1 = ori1.indexOf('s');
     let sum1 = 0;
     while (index1 !== -1) {
         sum1++;
         index1 = ori1.indexOf('s', index1 + 1)
     }
     console.log('s 出现的次数是' + sum1 + '次');*/

    ori = ori.split('')
    console.log(ori);
    var newStr = {};
//数组去重和计算出现的次数
    ori.forEach(function (item) {
        if (newStr[item]) {
            newStr[item]++;
        } else {
            newStr[item] = 1;
        }
    })
    var max = 0;
    var strkey = null;
    for (var key in newStr) {
        if (newStr[key] > max) {
            max = newStr[key];
            strkey = key;
        }
    }
    console.log("最多的字符是" + strkey);
    console.log("出现的次数是" + max);

    function fnu(ori,s){
        var mun = 0;
    [...ori].forEach(element => {
        if (element == s) {
            mun++;
        }
        return mun;
    });
    }
    fun()
    
// 定义一个数组和一个元素,获取该元素在数组中的位置集合
    var arr = [1, 2, 6, 4, 1, 1, 1, 3, 8]
    // 第一种方法
    var result1 = [];
    //求出该元素在数组里的第一个位置
    var index = arr.indexOf(1);
    // 使用 reduce 循环数组
    arr.reduce((element) => {
        //当index 不等于 -1 时输出 index 不过会陷入死循环 必须定义一个终止条件
        if (index !== -1) {
            // 这里没设有终止条件时会陷入死循环
            result1.push(index)
            // 使用 indexOf 查找 1 的索引号 找下一个 1 时是从第一个 1 后一位开始查找的所以得 index + 1 ,在将找到的相同元素赋值给index 再输出,开始下一次循环,直到循环jies为止
            index = arr.indexOf(1, index + 1);
        }
        return result1;
    });
    console.log(result1);

    //第二种方法
    function test01(arr) {

        var element = 1;
        var result2 = [];
        arr.reduce((pre, value, index) => {
            if (element == value) {
                result2.push(index)
            }
        }, []);
        return result2;
    }
    console.log(test01(arr));
    //第三种方法
    var index = arr.indexOf(1);
    var result3 = [];
    //利用 while 循环遍历数组 index 不等于 -1 
    while (index !== -1) {
        //输出index (这个会陷入死循环不要输出)
        result3.push(index)
        //再利用 indexOf 设置终止循环条件 
        index = arr.indexOf(1, index + 1)
    }
    console.log(result3);
// 写一个函数,求任意数组中数字的总和
    // 方法1
    function test02(arr1) {
        //定义一个存储数组中相加的总和
        var result = 0;
        for (let index = 0; index < arr1.length; index++) {
            const element = arr1[index];
            //  排除非数字:不是 number 是NaN 
            if (typeof (element) != 'number' || isNaN(element)) {
                //就跳过本次循环
                continue;
            }
            // 是数组里的数字类型的相加
            result += element;
        }
        // 返回总和
        return result;
    }
    console.log(test02([1, 'a', 2, 'b', 3, 'a', NaN, 'c', 'd', 'a', 'a']));

    function test03(arr2) {
        return arr2.reduce((pre, element, index) => {
            // 上一次的结果(默认的是 0)加上(数组中都不等于数字类型? (false) 或者 数组里都是数字类型的?(false))? 都是false,取值2
            pre += (typeof (element) != 'number' || isNaN(element)) ? 0 : element;
            // 返回数组里相加的总和
            return pre;
        }, 0);
    }
    console.log(test03([1, 'a', 2, 'b', 3, 'a', NaN, 'c', 'd', 'a', 'a']));
// 写一个函数,求任意数组中数字的最大值并返回
    //定义一个用于存储最大值的变量
    var max = arr[0];
    arr.reduce((per, element, index) => {
        if (max < element) {
            max = element
        }
    })
    console.log(max);
// 写一个函数,用数组的方式将短横线拼接的字符串转为大驼峰式命名,例如:product-name ====>ProductName
    var str = "product-name";
    function tf() {
        var arr = str.split("-");
        for (var i = 0; i < arr.length; i++) {
                // 1、substring(a,b)中的参数a其值可以从索引值0开始,
                // 当a等于0时,则表示其从字符串的第一个字符开始算起,
                // 也就是其子字符串是包含第一个字符的,当然,你也可以从后续的其他字符开始;

                // 2、substring(a,b)中的参数b,其值最大可以为 父字符串的长度,
                //但并不包含索引值为b的那个字符。
            arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].substring(1);
        }
        return arr.join("");
    };

    console.log(tf(str));
// 写一个函数,判断任意数组中的所有元素是否都为指定类型,如:判断数组arr中的所有元素是否都为number类型
// 写一个函数,判断素组元素是否全是number类型,如果是返回数组数字的平均数,不是返回NaN1
    var num = false;
    // 定义一个变量用于存储数组元素相加的总和
    var sum = 0;
    // 利用 filter 判断数组是否都是 number类型
    arr.filter((element, index) => {
        if (typeof (element) == 'number') {
            num = true;
            // 利用 reduce 求出数组的总和再赋值给 sum 
            sum = arr.reduce((pre, element, index) => {
                return (pre + element);
            }) / arr.length;
        } else {
            // 如果数组有其它数据类型则返回 NaN1
            console.log('NaN1');
        }
    })
    console.log(num);
    console.log(sum);
    /* sum = arr.reduce((pre, element, index) => {
        return (pre + element);
    });
    console.log(sum / arr.length); */
// 写一个函数,判断是否是升序排列
    function fn1(arr) {
        // 复制数组,并且新数组改变了旧数组不变
        var arrCopy = [...arr]
        // 利用 sort 给新数组进行升序
        arrCopy.sort((a, b) => a - b);
        console.log(arr);
        console.log(arrCopy);
        // 判断旧数组是否是升序并返回结果
        return arr.toString() == arrCopy.toString() ? '升序' : '非升序';
    }
    fn1(arr)
    console.log(fn1(arr));
// 写一个函数,去除数组中的重复值,并返回去重后的数组
    function fn(arr) {
        //定义一个新数组
        var newArr = []
        // 遍历旧数组
        for (let index = 0; index < arr.length; index++) {
            const element = arr[index];
            // 判断新数组里有没有旧数组里的值,如果没有就把它赋值给新数组
            if (newArr.indexOf(arr[index]) === -1) {
                // 使用 push 把旧数组的值添加到新数组里
                newArr.push(arr[index])
            }
        }
        return newArr;
    }
    console.log(fn(arr));
// 写一个函数,定义一个product对象的数组,每个product对象都有id和name属性,提取每个商品的的名称存到新数组并返回
    function fun3(arr) {
        var arrs = [
            { id: 1, name: 'admin1' },
            { id: 2, name: 'admin2' },
            { id: 3, name: 'admin3' },
            { id: 4, name: 'admin4' }
        ]
        /* var arrs1 = [];
      for (const value of arrs) {
           arrs1.push(value.name)
       } */
        return arrs.reduce((per, element, index) => {
            // 取出 name属性里的值并放入默认数组里
            per.push(element.name);
            // 返回默认数组
            return per
        }, []);
    }
    console.log(fun3(arr));
// 假设有原对象数组如下,写一个函数将该数组转为目标数组
    var goodsList = [
        { id: 1006002, name: "轻奢纯棉刺绣水洗四件套", brief: "设计师原款,精致绣花", categoryId: 1005000, categoryName: "居家" },
        { id: 1006007, name: "秋冬保暖加厚澳洲羊毛被", brief: "臻品级澳洲进口羊毛", categoryId: 1005000, categoryName: "居家" },
        { id: 1006013, name: "双宫茧桑蚕丝被 空调被", brief: "一级桑蚕丝,吸湿透气柔软", categoryId: 1005000, categoryName: "居家" },
        { id: 1006014, name: "双宫茧桑蚕丝被 子母被", brief: "双层子母被,四季皆可使用", categoryId: 1005000, categoryName: "居家" },
        { id: 1023003, name: "100年传世珐琅锅 全家系列", brief: "特质铸铁,大容量全家共享", categoryId: 1005001, categoryName: "餐厨" },
        { id: 1025005, name: "100年传世珐琅锅", brief: "特质铸铁,锁热节能", categoryId: 1005001, categoryName: "餐厨" },
        { id: 1038004, name: "100年传世珐琅锅 马卡龙系列", brief: "均匀导热,释放美味", categoryId: 1005001, categoryName: "餐厨" },
        { id: 1051000, name: "Carat钻石炒锅30cm", brief: "安全涂层,轻便无烟", categoryId: 1005001, categoryName: "餐厨" },
        { id: 1045000, name: "绿茶蛋黄酥 200克/4枚入", brief: "香甜茶食,果腹优选", categoryId: 1005002, categoryName: "饮食" },
        { id: 1070000, name: "星云酥 180克/3颗", brief: "酥饼界的小仙女", categoryId: 1005002, categoryName: "饮食" },
        { id: 1111007, name: "妙曲奇遇记曲奇礼盒 520克", brief: "六种口味,酥香脆爽", categoryId: 1005002, categoryName: "饮食" },
        { id: 1116011, name: "蔓越莓曲奇 200克", brief: "酥脆奶香,甜酸回味", categoryId: 1005002, categoryName: "饮食" },
    ];

    function fu(goodsList) {
        // 创建目标数组
        var categoryList = [];
        // forEach 遍历旧数组
        goodsList.forEach((element) => {
            //索引号的默认为0
            var copyIndex = 0;
            // some 循环新数组判断索引号的上的属性是否已经存在
            var result = categoryList.some((value, index) => {
                //每循环一次就把索引号赋值给 aarr,如果索引号上的属性(username)相同,那么它的值就会新增到相同的属性上
                copyIndex = index;
                // 判断旧数组里的索引号上的属性名是否已经存在新数组里
                return element.categoryId == value.categoryId;
            })
            // 如果已经存在就把 id name brief 属性名放入新数组的 goodsList 属性里
            if (result) {
                categoryList[copyIndex].goodsList.push({
                    id: element.id,
                    name: element.name,
                    brief: element.brief
                })
                // 如果不存在就把旧数组里相对应的属性放入新数组里
            } else {
                categoryList.push({
                    categoryId: element.categoryId,
                    categoryName: element.categoryName,
                    goodsList: [{
                        id: element.id,
                        name: element.name,
                        brief: element.brief
                    }]
                })
            }
        });
        //console.log(categoryList);
        return categoryList;
    }
    console.log(fu(goodsList));

    /* function fu(goodsList) {
        //定义一个目标数组
        var categoryList = [];
        // 要的是是它的回调函数,所以使用 forEach 循环遍历 旧数组goodsList
        goodsList.forEach((element) => {
            categoryList.push({
                    categoryId: element.categoryId,
                    categoryName: element.categoryName,
                    goodsList: [{
                        id: element.id,
                        name: element.name,
                        brief: element.brief
                    }]
                })
//用新数组(element)判断(some)目标数组的元素 (value) 是否存在旧数组里,
//如果不存在就把不存在的元素(element)放入目标数组里
            //定义索引号的默认值
            var copyIndex = 0;
            var result = categoryList.some((value, index) => {
                //把索引号赋值给 copyIndex
                copyIndex = index;
                return element.categoryId == value.categoryId;
            })
            //如果存在就把旧数组里的元素(element)商品信息存到新数组里对应分类的 goodsList下,
            if (result) {
                categoryList[copyIndex].goodsList.push({
                    id: element.id,
                    name: element.name,
                    brief: element.brief
                })
            } else {
                categoryList.push({
                    categoryId: element.categoryId,
                    categoryName: element.categoryName,
                    goodsList: [{
                        id: element.id,
                        name: element.name,
                        brief: element.brief
                    }]
                })
            } 
        });
         //console.log(categoryList);
         return categoryList;
    }
    console.log(fu(goodsList)); */

    // 假设有商品分类的数组如下,写一个函数,传入类别id,返回对应的类别名称 1001
    var categoryList = [
        {
            categoryId: 10,
            categoryName: '居家',
            categoryList: [
                {
                    categoryId: 1001,
                    categoryName: '家具'

                },
                {
                    categoryId: 1002,
                    categoryName: '被枕'
                },
                {
                    categoryId: 1003,
                    categoryName: '床品件套'
                },
                {
                    categoryId: 1004,
                    categoryName: '家饰'
                },
                {
                    categoryId: 1005,
                    categoryName: '宠物'
                }
            ]
        },
        {
            categoryId: 20,
            categoryName: '餐厨',
            categoryList: [
                {
                    categoryId: 2001,
                    categoryName: '锅具'
                },
                {
                    categoryId: 2002,
                    categoryName: '餐具'
                },
                {
                    categoryId: 2003,
                    categoryName: '清洁'
                },
                {
                    categoryId: 2004,
                    categoryName: '杯壶'
                },
                {
                    categoryId: 2005,
                    categoryName: '厨房电器'
                }
            ]
        }
    ]

    function test12(categoryList, id) {
        // 第三种: reduce
        return categoryList.reduce((pre, element) => {
            // 使用分支循环语句,判断条件:默认值 不等于 '不存在' 
            // 开始时需要直接拦截默认值,如果等于默认值时,内圈的结果会被默认值覆盖
            if (pre != '不存在') {
                return pre;
            }
            // 使用分支循环语句, 判断条件:传入的id和对应元素的categoryId是否相等
            if (element.categoryId == id) {
                // 上一次回调函数的结果 等于 元素的categoryName
                pre = (element.categoryName);
            }
            // 若不相等,判断条件: 元素element的categoryList是否存在  内层是否存在
            else if (element.categoryList) {
                // 若拥有内层,传入数据判断 递归函数
                var result = test12(element.categoryList, id);
                if (result) {
                    return result
                }
            }

            // 若没有内层将结果pre(categoryName)返回 
            return pre;
        }, '不存在')
    }
    console.log(test12(categoryList, 10)); // 居家
    console.log(test12(categoryList, 1001)); // 家具
    console.log(test12(categoryList, 1001001)); // 沙发
    console.log(test12(categoryList, 1001001001)); // '不存在'
</script>