JS数组

什么是数组

  • 数组(Array)是有序数据集合
  • 数组中的每个成员被称为元素(Element),每个元素的名称(键)被称为数组下标(index)
  • 数组内不同元素的值可以为不同类型
  • 数组的长度是弹性的、可读写的
  • 在Javascript脚本中数组主要用于临时寄存同类数据,进行高速批量运算。
var arr = [123,"abc",null,undefined,{name:"xioawang"},true,[1,2,3],function () {
    alert(1);
}];
console.log(arr);
// arr[arr.length - 1]();
arr.length = 100;
console.log(arr);

定义数组和读写数组

构造数组

  • 使用new运算符调用Array()类型函数时,可以构造一个新数组
  • 直接调用Array函数,不传递参数,可以创建一个空数组
  • 传递多个值,可以创建一个实数组
  • 传递一个数值参数,可以定义数组的长度,即包含元素的个数,参数值等于数组的length属性值,每个元素的值默认值为 undefined
  • 使用中括号可以读写数组,中括号左侧是数组名称,中括号内为数组下标
// 1.构造数组:
var arr1 = new Array();//如果不传值,则构造一个空数组
console.log(arr1);

var arr2 = new Array("a","b",23,45);
console.log(arr2);

var arr3 = new Array(4);
console.log(arr3);//如果传递一个参数,是定义数组的长度

var arr4 = new Array("a");
console.log(arr4);

console.log(arr2[2]);//读取数组的值

数组直接量

数组直接量的语法格式:在中括号中包含多个值列表,值之间用号分隔(推荐使用数组直接量定文d 数组,因为数组直接量是定义数组最简便、最高效的方法)

    var arr5 = [1,2,3,4,5];//直接量定义数组
    console.log(arr5);
    console.log(arr5[3]);//读取数组

多维数组

  • Javascript不支持多维数组,设置元素的值等于数组,可以模拟二维数组结构,如果三维组中每个元素的值也为数组,则可以模拟三维数组,以此类推,通过数组套的形式可以定义多推数组
  • 读写多维数组方法与普通方法相同,都是使用中括号进行访问
var arr6 = [1,2,3,[4,5,6],7];//定义一个二维数组
console.log(arr6);
console.log(arr6[3][1]);//二维数组的获取值
var arr7 = [1,2,3,4,5,[5,6,7,[8,9],11],10];//定义一个三维数组
console.log(arr7);
console.log(arr7[5][3][1]);//三维数组的获取



//使用for 把1-100的整数以二维的形式储存在数组中
var arr8 = [];
// 遍历10次,每次生成一个10个值的数组
for (var i = 0; i < 10; i++) {
    // 创建一个新数组,每次遍历的时候,插入10个值,然后把这个数组,插入到arr8中
    var arr9 = [];
    //遍历10次,每次向arr9中插入1个值
    for (var j = 0; j < 10; j++) {
        arr9[j] = i * 10 + j + 1;
    }
    arr8[i] = arr9;
}
console.log(arr8);

空位数组

  • 空位数组就是数组中包含空元素。所谓空元素,就是在语法上数组中两个逗号之间没有任何值。出现空位数组的情况如下
    • 直接量定义
    • 构造函数定义
    • delete删除
  • 空元素可以读写, length属性不排斥空位,如果使用for语句和 length属性遍历数组,空元素都可以 被读取,空元素返回值为undefined
var arr10 = [1,2,,4];//空位数组,找不到,所以空位的值返回undefined
var arr11 = [1,2,undefined,4];//有值,值为undefined
console.log(arr10);
console.log(arr11);

关联数组

  • 如果数组的下标值超出范围,如负数、浮点数、布尔值、对象或其他值,js会自动把它转换为一个字符串,并定义为关联数组。
  • 关联数组就是与数组关联的对象,简单地说就是数组对象,字符串下标就是数组对象的属性
    var arr12 = [1,2];
    arr12[3.1] = "haha";//相当于给数组扩展了一些属性和方法
    arr12[true] = "buer";
    console.log(arr12);
    console.log(arr12[3.1]);

伪类数组

  • 伪类数组,也称为类数组,即类似数组结构的对象。
  • 简单地说,就是对象的属性名为非负整数,且从0开始,有序递增,同时包含length属性,还应确保其值与有序下标属性个数保持动态一致,以方便对伪类数组进行选代操作。
  • 由于数字数非法标识符,所以需要用中括号来读写属性
    var obj1 = {
      0:"a",
      1:"2",
      2:"c",
      3:"d",
      length:4
    }
    console.log(obj1[1]);

斐波那契数列

//打印出斐波那契数列的前100个值 在数组中
// 1,2,3,5,8,13 初始值1和2   其他的值是前两个值的和
// arr[6] = arr[4]+arr[5]
var arr = [1,2];
for (var i = 2; i < 100; i++) {
    arr[i] = arr[i-2] + arr[i-1];
}
console.log(arr);

数组的长度

  • 每个数组都有一个length属性,该属性返回数组的最大长度。
  • length属性可读可写,是一个动态属性。
  • length属性值也会随数组元素的变化而自动更新。同时如果重置了length属性值,也将影响数组的元素。
var arr1 = [];
arr1.length = 100;
console.log(arr1);//empty*100
console.log(arr1[10]);//undefined

var arr2 = [1,2,3];
arr2.length = 5;
console.log(arr2);

var arr3 = [1,2,3,4,5,6,7];
arr3.length = 2;
console.log(arr3);//[1,2]

操作数组

栈操作

  • 使用push()和pop()方法,可以在数组的尾部执行操作。
  • 其中push方法,能够把一个或多个参数附加到数组的尾部,并返回附加元素以后,数组的长度
  • pop方法是能够删除数组中的最后一个元素,并返回删除的值
  • 补充:栈是先进后出,后进先出的原则。类似的情况是,叠放物品,或者子弹上膛
var arr = [];//空栈
console.log(arr.push(1));//入栈 返回新长度
console.log(arr.push(2,3));//入栈 一次可以插入多个值 返回新长度
console.log(arr);

console.log(arr.pop());//出栈 返回删除的值
console.log(arr.pop());//出栈 返回删除的值
console.log(arr);
  • 栈操作练习
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>栈操作练习 -进制转换</title>
</head>
<body>
<script>
    function to2b(num) {
        var arr = [];//一个新栈,把每次生成的余数压到栈里
        var r = null;//用来保存每次生成的余数
        var s = "";//最后返回的二进制字符串
        while(num > 0){
            r = num % 2;//求出每次的余数
            arr.push(r);//把余数入栈
            num = parseInt(num / 2);//求出num计算后的值 并向下取整
        }
        while(arr.length > 0){
            s += arr.pop();//pop是把最后一个值删了 并返回出来 和s拼接  放在了s的首位
        }
        return s;
    }

    console.log(to2b(100));
    console.log(to2b(1000));
    console.log(to2b(3));
    // console.log((100).toString(2));//1100100
</script>
</body>
</html>
  • 栈数据结构方法封装
var arr = [3,5,2,3,6,1,6];
// push:添加一个新元素到栈顶
function push(arr) {
    // arguments
    for (var i = 1; i < arguments.length; i++) {
        arr.push(arguments[i]);
    }
}
push(arr,1,2,3)

// pop方法 移出栈顶的元素  并且得到移出的值
function pop(arr) {
    return arr.pop();
}

// peek:返回栈顶元素 不对栈做修改
function peek(arr) {
    return arr[arr.length - 1]
}

// console.log(peek(arr));

// isEmpty 判断栈中是否为空  如果为空则返回true 否则返回false
function isEmpty(arr) {
    return arr.length == 0
}

// clear:清空整个栈
function clear(arr) {
    arr.length = 0;
}

// size:返回栈里的个数
function size(arr) {
    return arr.length;
}
  • 栈结构练习-可定制的进制转换
//封装一个栈操作的一个类  想要使用 直接new 实例化
//实例化得到的对象 就会拥有这些方法
function Stack() {
    this.arr = [];
    this.push = function (item) {
        this.arr.push(item);
    };
    this.pop = function () {
        return this.arr.pop();
    };
    this.peek = function () {
        return this.arr[this.arr.length - 1];
    };
    this.isEmpty =function () {
        return this.arr.length == 0;
    };
    this.clear = function () {
        this.arr = [];
    };
    this.size = function () {
        return this.arr.length;
    };
}

// 16进制以下所有进制转换算法
function divideBy2(num,para) {
    //把Stack实例化以后  所有的remStack就会拥有Stack这个类的属性和方法
    var remStack = new Stack();
    var rem;
    var binarySting = "";
    var str = "0123456789abcdef";
    //循环插入栈
    while(num>0){
        rem = parseInt(num % para);
        remStack.push(rem);
        num = parseInt(num / para);
    }
    // 当全部插入完成以后,对栈进行一个移出的操作
    while(!remStack.isEmpty()){

        binarySting += str[remStack.pop()];
    }
    return binarySting;
}

console.log(divideBy2(2821355,12));
console.log(divideBy2(4,16));

队列操作

  • 使用unshift()和 shift()方法可以在数组头部执行操作
  • 其中unshift()能够把一个或多个参数值附加到数组的头部,第1个参数为数组新的元素0,第2个参数为新的元素1,以此类推,最后返回添加元素后的数组长度
  • shift方法能够删除数组第1s个元素,并返回该元素,然后将余下所有元素前移1位,以填补数组头部的空缺。如果数组为空, shift将不进行任何操作,返回 undefined
  • 使用 unshift分批插入元素与一次性插入元素结果是不同的
  • 将pop()与 unshift()方法结合,或者将 push()与 shift()方法结合使用,可以模拟队列
// 利用队列模式把数组元素的所有值放大10倍
var a = [1,2,3,4,5];
for(var i in a){
    var t = a.pop();
    a.unshift(t*10);
}
console.log(a);
  • 补充:队列也是一种运算受限的线性表,不过与栈操作不同,队列只允许在一端进行插入操作,在另一端进行删除操作。
  • 队列通循先进先出、后进后出的原则,类似的行为在生活中比较常见,如排队购物、任务排序等。在 Javascript动画设计中,也会用到队列操作来设计回调函数。
  • 击鼓传花练习
// 猴子找大王游戏
// 有一群猴子排成一圈,按1、2、3、…、n依次编号,然后从第1只开始数,数到第m只,则把它踢出圈,然后从它后面再开始数,当再次数到第m只,继续把它踢出去,以此类推,直到只剩下一只猴子为止,那只猴子就叫作大王。要求编程模拟此过程,输入m和n,输出最后那个大王的编号
// n表示猴子个数,m表示踢出位置
function f(n,m){
    //将猴子编号并放入数组
    var arr = [];
    for(var i = 1;i < n+1;i++){
        arr.push(i);
    }
    //当数组内只剩下一只猴子的时候跳出循环
    while(arr.lenght>1){
        //定义排队轮转次数
        for(var i = 0;i<m-1;i++){
            //队列操作完成轮转
            arr.push(arr.shisft());
        }
        arr.shift();//提出第m只猴子
    }
    return arr;
}
  • 队列结构的封装
/*  enqueue:向队列的尾部添加新的项
    dequeue:移除队列的第一个项,并返回被移除的元素
    front:返回队列的第一个元素,队列不做任何的改动
    isEmpty:如果队列中不包含任何元素,返回true,则返回true,否则返回false
    size:返回队列包含的元素个数
*/

function Queue() {
    this.arr = [];
    this.enqueue = function (item) {
        this.arr.push(item)
    }
    this.dequeue = function () {
        this.arr.shift();
    }
    this.front = function () {
        return this.arr[0];
    }
    this.isEmpty = function () {
        // return this.arr.length == 0;
        return !this.arr.length;
    }
    this.size = function () {
        return this.arr.length;
    }
}

var queue1 = new Queue();

删除元素

  • 使用pop方法可以删除尾部的元素,使用shift方法可以删除头部的元素
  • 使用delete运算符能删除指定下标位置的数组元素,删除后的元素为空位元素,删除数组length保持不变
  • 使用length属性可以删除尾部一个或多个元素,甚至可以清空整个数组
  • 使用splice方法可以删除指定下标位置后一个或多个数组元素(个数)
// 使用delete删除指定下标的元素
var arr1 = [1,2,3,4,5];
delete arr1[2];//删除指定下标的值,当前的值为空,所以数组变成了空位数组 长度不变
console.log(arr1);

// 使用length属性也可以删除数组
var arr2 = [1,2,3,4];
arr2.length = 1;
console.log(arr2);


var arr3  = [1,2,3,4,5,5,6,7,8,8];
console.log(arr3.splice(3));//一个参数代表删到末尾
console.log(arr3);//[1,2,3]

var arr4  = [1,2,3,4,5,5,6,7,8,8];
console.log(arr4.splice(3,3));//两个个参数代表删几个 [4,5,5]
console.log(arr4);//[1,2,3,6,7,8,8]

添加元素

  • 使用 push方法可以在尾部添加一个或多个元素,使用 unshift方法可以在头部附加一个或多个元素
  • 通过中括号和下标值,可以为数组指定下标位置添加新元法来添加元素
  • concat方法能够把传递的所有参数按顺序添加到数组的尾部
    • concat方法可以跟随多个参数,并把它们作为元素按顺序连接到数组的尾部
    • 如果参数是数组,则concat方法会把它打散,分别作为单独的元素连接到数组的尾部
    • 不过concat方法仅能够打散一维数组,它不会打散二维的数组。
    • concat方法将创建并返回一个新数组,而不是在原来数组基础上添加新元素。所以,如果要在原数组着础上添加元素,建议使用 push方法和unshift方法来实现。但是 push方法和 unshift方法不能够打散参数数组,而是把它作为单独的参数执行添加操作
  • 使用 splice方法在指定下标位置后添加一个或多个元素
// 可以使用中括号和下标值 来添加元素,或者是修改元素
var arr1 = [1,2,3,4,5];
arr1[5] = 6;
arr1[10] = 10;//如果给后边元素设置值,中间的空白就变成了空位元素
arr1[1] = "a";//这种方法只能给空位元素设置,或者是其他的没有的位置设置,否则就修改了元素
console.log(arr1);

// concat方法
var arr2 = ["a","b","c"];
console.log(arr2.concat(1, 2, 3));;
console.log(arr2);//原数组不改变

var arr2 = ["a","b","c"];
arr2.push([1,2,3]);//push插入会把数组直接当成1个值插入
console.log(arr2);

var arr2 = ["a","b","c"];
console.log(arr2.concat([1, 2, 3,[4,4,4]]));

// splice方法可以在指定位置的下标添加元素
var arr3 = ["a","b","c","d","e","f"];
arr3.splice(2,0,"g","h");//无论是否删除,都会把第三个参数以后的所有参数 按顺序放在第一个参数下标标记的位置
console.log(arr3);

使用 splice()方法

  • splice()方法的参数都是可选的。如果不给它传递参数,则该方法不执行任何操作
  • 如果给它传递一个数,则该方法仅执行删除操作,参数值指定删除元素的起始下标(包括该下标元素),splice方法将删除后面所有
  • 如果指定两个参数,则第2个参数值表示要别删除元素的个数。
  • 如果指定三个或多个参数,则第3个以及后面所有参数都被视为插入的元素
  • 如果不执行删除操作,第2个参数值应该设置为0,但是不能够空缺,否则该方法无效
  • splice方法执行的返回值是被别除的子数组
  • 当第1个参数值大于length属性值时,被视为在数组尾部执行操作,因此删除无效,但是可以在尾部插入多个指定元素
  • 参数取负值问题。如果第1个参数为负值,则按绝对值从数组右侧开始向左侧定位。如果第2个参数为负值,则被视为0。
var arr1 = [1,2,3,4,5,6,7];
console.log(arr1.splice(4));//[5,6,7]
console.log(arr1);//[1,2,3,4]

var arr2 = [1,2,3,4,5,6,7];
console.log(arr2.splice(1,3));//[2,3,4]
console.log(arr1);//[1,5,6,7]

var arr3 = [1,2,3,4,5,6,7];
console.log(arr3.splice(2,1,"a","b","c"));//[3]
console.log(arr3);//[1,2,a,b,c,4,5,6,7]

var arr4 = [1,2,3,4,5,6,7];
console.log(arr4.splice(10,2,"a","b","c"));//[]
console.log(arr4);//[1,2,3,4,5,6,7,a,b,c]

var arr5 = [1,2,3,4,5,6,7];
console.log(arr5.splice(-5,2,"a","b","c"));//[3,4]
console.log(arr5);//[1,2,a,b,c,5,6,7]

var arr5 = [1,2,3,4,5,6,7];
console.log(arr5.splice(-5,-2,"a","b","c"));//[]
console.log(arr5);//[1,2,a,b,c,3,4,5,6,7]

使用slice()方法

  • slice方法与splice方法功能相近,但是它仅能够截取数组中指定区段的元素,并返回这个子数组
  • 该方法包含两个参数,分别指定截取子数组的起始和结束位置的下标
  • 第1个参数指定起始下标位置,包括该值指定的元素;第2个参数指定结束位置,不包括指定的元素。
  • 该方法的参数可以自由设置。如果不传递参数,则不会执行任何操作:如果仅指定一个参数,则表示从该参数值指定的下标位置开始,截取到数组的尾部所有元素
  • 当参数为负值时,表示按从右到左的顺序进行定位,即倒数定位法,而不再按正数顺序定位(从左到右),但取值顺序依然是从左到右,如果起始下标值大于或等于结束下标值,将不执行任何操作
  • sliced方法将返回数组的一部分(子数组),但不会修改原数组
var arr1 = [1,2,3,4,5,6,7,8];
console.log(arr1.slice(3));//[4,5,6,7,8]
console.log(arr1);

var arr1 = [1,2,3,4,5,6,7,8];
console.log(arr1.slice(3,6));//[4,5,6]
console.log(arr1);

var arr1 = [1,2,3,4,5,6,7,8];
console.log(arr1.slice(-3,6));//[6]
console.log(arr1.slice(-6,5));//[3,4,5]

数组排序-reverse方法

  • reverse方法能够颠倒数组元素的排列顺序,该方法不需要参数
  • 改变原来数组,不创建新数组
var arr = [1,2,"a","2","b",1,[1]];
console.log(arr.reverse());
console.log(arr);


// 手写reverse反转
function reverse(arr) {
    var newArr = [];
    for(var i in arr){
        newArr.unshift(arr[i]);
    }
    return newArr;
}
console.log(reverse([1, 4, 3, 2, 5, 1]));

数组排序 - sort方法

  • sort方法能够根据一定条件对数组元素进行排序。如果调用sort方法时没有传递参数,则按字母顺序对数组中的元素进行排序。
  • sort方法可以根据其他顺序执行操作。这时就必须为方法提供一个函数参数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字
var arr = [1,2,3,4,22,34,32,34,100];
console.log(arr.sort());
console.log(arr);

var arr = [1,2,4,3,22,34,32,34,100];
arr.sort(function (a,b) {
    console.log(a,b)
    //sort每次传入两个值,第一个参数a是后边的值,第二个参数b是前边的值
    //如果返回的正数,则两个值不交换位置,如果返回的是负数,则两个值交换位置
    if (a > b){
        return 1;
    }else if(a < b){
        return -1;
    }else{
        return 0;
    }
});
arr.sort(function (a,b) {
    return a - b;//升序排列
})
console.log(arr);

var arr = [1,2,4,3,22,34,32,34,100];
arr.sort(function (a,b) {
    if (a > b){
        return -1;
    }else if(a < b){
        return 1;
    }else{
        return 0;
    }
});

arr.sort(function(a,b){
    // return -(a - b);//降序
    return b - a;
})
console.log(arr);
  • 对对象进行排序
    // 对对象进行排序:
    var persons = [
        {name:"lily1",sex:"女",age:18},
        {name:"lily2",sex:"女",age:19},
        {name:"lily3",sex:"女",age:11},
        {name:"lily4",sex:"女",age:28},
        {name:"lily5",sex:"女",age:22},
        ]
    
    //请对数组persons进行按照年龄升序排序
    persons.sort(function (a,b) {
        if (a.age>b.age) {
            return 1;
        }else if(a.age<b.age){
            return -1;
        }else{
            return 0;
        }
    })
    console.log(persons);
  • 动态加载数据,及对象数据排序

<!-- 动态加载数据,及对象数据排序 -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button id="price">价格排序</button>
<button id="hot">热度排序</button>
<button id="num">销量排序</button>
<ul id="list">
    <li class="outer">
        <h2>苹果手机</h2>
        <p>销量:<span>10000</span></p>
        <p>价格:<span>11988</span></p>
        <p>热度:<span>299</span></p>
    </li>
    <li>
        <h2>苹果手机</h2>
        <p>销量:<span>10000</span></p>
        <p>价格:<span>11988</span></p>
        <p>热度:<span>299</span></p>
    </li>
    <li>
        <h2>苹果手机</h2>
        <p>销量:<span>10000</span></p>
        <p>价格:<span>11988</span></p>
        <p>热度:<span>299</span></p>
    </li>
</ul>
<script>
    var oList = document.getElementById("list");
    var oPrice = document.getElementById("price");
    var oHot = document.getElementById("hot");
    var oNum = document.getElementById("num");
    var data ={
        phone:[
            {brand:"苹果手机",num:"10000",price:"11988",hot:"199"},
            {brand:"联想手机",num:"9000",price:"1988",hot:"1199"},
            {brand:"华为手机",num:"20000",price:"12988",hot:"1299"},
            {brand:"三星手机",num:"13000",price:"7988",hot:"3199"},
            {brand:"魅族手机",num:"4000",price:"988",hot:"1099"},
            {brand:"小米手机",num:"14000",price:"19988",hot:"109"},
            {brand:"锤子手机",num:"100",price:"88",hot:"199999"},
        ],
        img:[
            "01.jpg","02.jpg","03.jpg"
        ]
    }
    var phoneDate = data.phone;
    showPhone(phoneDate);
    function showPhone(data) {
        oList.innerHTML = "";
        for(var i in data){
            var str = `
                <li>
                    <h2>${data[i].brand}</h2>
                    <p>销量:<span>${data[i].num}</span></p>
                    <p>价格:<span>${data[i].price}</span></p>
                    <p>热度:<span>${data[i].hot}</span></p>
                </li>
            `;
            oList.innerHTML += str;
        }
    }

    // 点击价格降序
    oPrice.onclick = function () {
        phoneDate.sort(function (a,b) {
            if (+a.price > +b.price){
                return -1;
            }else{
                return 1;
            }
        })
        //当数据发生变化以后,再次调用字符串拼接函数,重新向页面赋值
        showPhone(phoneDate);

    }

    // 点击热度降序
    oHot.onclick = function () {
        phoneDate.sort(function (a,b) {
            if (+a.hot > +b.hot){
                return -1;
            }else{
                return 1;
            }
        })
        //当数据发生变化以后,再次调用字符串拼接函数,重新向页面赋值
        showPhone(phoneDate);

    }

    // 点击热度降序
    oNum.onclick = function () {
        phoneDate.sort(function (a,b) {
            if (+a.num > +b.num){
                return -1;
            }else{
                return 1;
            }
        })
        //当数据发生变化以后,再次调用字符串拼接函数,重新向页面赋值
        showPhone(phoneDate);

    }

</script>
</body>
</html>

数组转换 - toString()

  • 数组中 toString把每一个元素转为字符串,然后是使用逗号连接输出显示。
  • 当数组用于字符串环境中时,JS会自动调用toString()方法把数组转为字符串。
var arr = [1,2,"a",null,{name:"lily"}];//null和undefined没有toString方法
console.log(arr.toString());//1,2,a,,[object Object]

//改写Array的toString方法
Array.prototype.toString = function () {
    alert(1);
    return "没有返回值 哈哈哈"
}
var arr = [1,2,3];
console.log(arr + "1");
// console.log(arr); 

数组转换 - toLocalString()

  • toLocalString方法和toString方法相同,主要区别在于toLocalString方法能够使用户所在地区特定的分隔符把生成的字符串连接起来。
  • 根据中国习惯,先把数字转为浮点数之后,再执行字符串
    var arr = ["1.00",222222,3,4,"a"];
    console.log(arr.toLocaleString());
    console.log(arr.toString());

数组转换 - join()

  • join方法可以把数组转换为字符串,不过它可以指定分隔符,在调用join方法时,可以传递一个参数作为分隔符来连接每个元素,如果省略参数,默认使用逗号作为分隔符,这时与toString方法转换操作效果相同。
  • 返回一个转换后的字符串,并没有改变原数组
  • 如果不想要间隔 可以输入一个空字符串
  • 如果数组的值是其他类型 在数组中 如果遇到null或者undefined 直接转换成空字符串 其他按照toString规则转换
var arr = ['1',2,'c',4,5,null];
console.log(arr.join());//返回字符串
console.log(arr);

console.log(arr.join("-"));//返回字符串
console.log(arr.join(""));//返回字符串

元素定位 - indexOf 和 lastIndexOf

  • 使用indexOf和lastIndexOf方法可以检索数组元素,返回指定元素的索引位置

  • indexof返回某个元素值在数组中的第1个匹配项的索引,如果没有找到指定的值,则返回-1.

  • 第二个参数可选,表示开始搜索的数组索引。如果省略,则从索引0处开始搜索

  • lastIndexOf返回指定的值在数组中的最后一个匹配项的索引,用法和indexOf相同

    var arr = ["xiaowang","xiaoli","xiaozhang","xiaoqian","xiaomao","xiaozhang","xiaozhang2"];
    var userStr = "xiaozhang";
    var userStr2 = "maoge";
    console.log(arr.indexOf(userStr,3));
    console.log(arr.indexOf(userStr));
    console.log(arr.indexOf(userStr,6));
    console.log(arr.indexOf(userStr2));
    
    

console.log(arr.lastIndexOf("xiaozhang",2));//第二个参数是限制某一个范围,返回的仍然是下标




### 检测数组

- isArray是Array类型的一个静态方法,使用它可以判断一个值是否为数组。
- 使用 Array.isArray();
- typeOf运算符只能显示数组的类型是Object,而 Array.isArray方法可以直接返回布尔值。在条件表达式中,使用该方法非常实用.
- 使用in运算符可以检测某个值是否存在于数组中,注意,in运算符主要用于对象,但也适用于数组



```js
var  a = "123";
var b = [6,2,3,4];
console.log(Array.isArray(a));//false
console.log(Array.isArray(b));//true
console.log(6 in b);//false

var obj = {
    name:"xiaowang",
    sex:"nan"
}
console.log('name' in obj);

检测是否全部符合-every方法

  • every方法可以测试的所有元素是否都满足指定的测试
  • every中是函数,每一项数组的值,依次进入函数运行,函数最终要要求返回布尔值。
  • 如果有一项返回false,则停止执行,every返回false
  • 如果所有的项全部返回true 那么 整个every方法就返回true
  • every方法的回调函数拥有3个参数:1、item 数组的每一项 2、index 数组的这一项 对应的下标 3、array 原数组
  • every方法还有第二个可选的参数,可在回调函数中为其引用this关键字的对象。如果省略,则undefined是this值
// 我们得到一组年龄,如果所有的人都成年了,那么我们就开启成人网吧模式,否则 就进入儿童模式
var userAges = [18,19,19,19,22,29,50,80,45];
var isPerson = userAges.every(function (item,index,array) {
    console.log(item,index,array);
    var re = true;
    if (item < 18){
        re = false;
    }
    return re;
});
if (isPerson){
    alert("进入成人模式  坐稳了")
}else{
    alert("儿童模式")
}

// 可以简单点:
var isPerson = userAges.every(function (item,index,array) {
    return item >= 18;
});
if (isPerson){
    alert("进入成人模式  坐稳了")
}else{
    alert("儿童模式")
}


// 检测数组中的数是否都是偶数
var arr = [1,2,3,4];
var isEven = arr.every(function(item,index,arr){
    if(item % 2 == 0){
        return true;
    }else{
        return false
    }
})
if(isEven){
    console.log("偶数")
}else{
    console.log("不全是偶数")
}


//检测数组中元素的值是否都在指定的范围内,返回值用一个对象设置
var obj = {max:20,min:10};
var arr = [12,13,19];
var isScope = arr.every(function(item){
    if(typeof item !== "number"){
        return false
    }else{
        return item>=this.min && item <=this.max
    }

},obj)

检测是否存在符合 - some方法

  • 使用some方法可以确定数组的元素是否有满足指定的测试的项
  • 只要一项返回true 那么 some方法就返回true(一真即真)
  • 其余和every类似
// 我们得到一组年龄,如果所有的人都成年了,那么我们就开启成人网吧模式,否则 就进入儿童模式
var userAge = [19,18,21,23,14,45];
var isPerson = userAge.some(function (item,index,array) {
    return item < 18;
});
if (isPerson){
    alert("儿童模式")
} else{
    alert("成人模式")
}


//this指向对象的
var arr = [18,19,20,21,30,11,14,19,40];
var isTrue = arr.some(function (item,index,array) {
    // return item < 18;
    return item < this.max;
},{max:18})
console.log(isTrue);

for迭代数组

  • for和for/in语句都可以迭代数组,for语句需要配合length属性和数组的下标实现。执行效率没有for/in高。
  • for/in 也会跳过空元素
var arr = ["a","b","c",,"e"];
for (var i = 0; i < arr.length; i++) {
    console.log(arr[i]);//a b c undefined e
}

for(var j in arr){
    console.log(j,arr[j]);//a b c e
}

forEach

  • Array类型为每一个数组定义了forEach方法,可以对数组进行迭代操作
  • forEach中一个迭代函数,一个可选的this引用的对象
  • 不会对空元素调用回掉函数
  • foreach方法 用来遍历数组的每一项 forEach方法没有返回值
// 使用forEach迭代数组,计算数组元素的和

//一个家庭的年龄 过年了  每个人长1岁
//方法1 创建一个新数组
var userAages = [19,21,18,34,32,25,45];
var newUserAges = [];
userAages.forEach(function (item,index,array) {
    newUserAges[index] = item + 1;
})
console.log(newUserAges);
//方法2 直接改变原来数组
var re = userAages.forEach(function (item,index,array) {
    userAages[index] = item + 1;
})
console.log(userAages);
console.log(re);

使用keys迭代

  • keys()是Object的静态函数,专门用来遍历对象获取键名, Object.keys函数的参数是一个对象,返回一个数组,元素是该对象所有本地属性名。
  • 如果使用该函数选代数组,可以汇集数组的所有元素下标值。
  • 除了获取键名集合外,使用keys还可以间接统计对象的长度
  • Object还有一个类似的静态函数: getOwnPropertyNames,与keys用法相同,参数都是对象,返回值都是数组,数组元素都是属性名。不同点:keys仅能选代本地、可枚举的属性, getownPropertyNames可以迭代所有
var arr = ["a","b","c",,"d"];
console.log(Object.keys(arr));;

映射数组

  • 使用map方法可以对数组的每一个元素调用指定的回调函数,并返回包含结果的数组。
  • arr.map(function(){},thisArg)
  • map方法返回一个新数组,其中每一个元素均为关联的原始数组元素的回调函数返回值。
  • map不会为缺失的元素调用回调函数
//把数组中的每个元素的值平方,乘以PI的值,把返回的圆的面积作为新数组的元素值,最后返回这个新数组

// 有一个数组装着2019年所有人的年龄,2020年以后,每个人的年龄都增加1岁
var allAge = [19,15,,2,30,32,43,45];
var age2020 = allAge.map(function (item,index,arr) {
    return item+1;
})
console.log(age2020);


//回调函数可以使用系统的内置函数
var a = [25,36];
var b = a.map(Math.sqrt);
console.log(b);//[5,6]

//练习
var re = [1,2,3].map(parseInt);
console.log(re);//[1,NaN,NaN]

console.log(parseInt(1, 0));//1
console.log(parseInt(2, 1));//NaN
console.log(parseInt(3, 2));//NaN

数组过滤

  • 使用filter方法可以返回数组中满足指定条件的元素。
  • array.filter(function,thisArg)
  • 返回值是一个包含回掉函数为其返回ture的所有值的新数组。如果回调函数为array的所有元素返回false,则新数组长度为0.
  • 不会缺少的元素调用回调函数
// 筛选出所有的偶数
var arr = [1,2,3,4,5,6,6,7,8,9];
var evenArr = arr.filter(function (item,index,array) {
    return item % 2 == 0
})
console.log(evenArr);//[2,4,6,6,8]

function f(item,index,array) {
    return item % 2 == 0;
}
var evenArr = arr.filter(f);
console.log(evenArr);


// 使用filter过滤掉不符合条件的值
var obj = {max:80,min:14};
var age = [12,11,34,56,90,92,65,65,34,31];
var newAge = age.filter(function (item) {
    return item >= this.min && item <= this.max;
},obj)
console.log(newAge);

reduce

  • reduce方法可对数组的所有元素调用指定的回调函数。
  • 该回调函数的返回值为累计结果,并且此返回值在下一次调用该回调函数的时候作为参 数提供
  • reduce方法的参数函数可以是4个参数:上一次调用回调函数的返回值,如果提供了reduce的第二个参数,则第一次调用回调函数时,初始值是reduce方法的第二个参数;当前元数组元素的值;元素索引;数组对象
  • reduce方法的最终返回值是通过最后一次调用回调函数获得的累计结果。
// 用-把数组的各个值分开‘
var arr = ["abc","def","ggg","uuu"];
var newStr = arr.reduce(function (a,b,c,d) {
    return a + "-" + b;
},"oh")
console.log(newStr);//oh-abc-def-ggg-uuu
// 数组 arr = [1,2,3,4] 求数组的和
var arr = [1,2,3,4];
arr.reduce(function(pre,cur){return pre + cur}); // return 10

// 计算数组最大值
var max = arr.reduce(function (prev, cur) {
    return Math.max(prev,cur);
});

数组方法总结

数组练习

  • 将数组的0去掉
  • 数组排序去重
  • 返回数组的最大最小值
  • 求一组数中的所有数的和和平均值
  • 求一组数中的最大值和最小值,以及所在位置
  • 翻转数组
  • 冒泡排序,从小到大
// 将数组的0去掉
var arr = [1,3,4,0,6,4,0,4,5];
var newArr = [];
arr.forEach(function (item,index,array) {
    if (item == 0){
        // 当等于0的时候,我们不是要退出循环 而是退出这个函数
        return;
    }
    newArr.push(item);
})
console.log(newArr);
// 数组排序去重
var arr = [1,3,2,2,4,2,1,6,4,2];
// 先排序 后去重

arr.sort(function (a,b) {
    return a-b;
})
console.log(arr);
var newArr = [];
for (var i = 0; i < arr.length; i++) {
    if (arr[i] == arr[i+1]){
        continue;
    }
    newArr.push(arr[i]);
}
console.log(newArr);
var arr = [1,3,56,43,78,32,67,34,0,87];
var min = 100;
var max = 0;
for (var i = 0; i < arr.length; i++) {
    if (min > arr[i]){
        min = arr[i];
    }
    if (max < arr[i]){
        max = arr[i];
    }
}
console.log(min,max)
posted @ 2023-01-12 21:52  z_bky  阅读(46)  评论(0)    收藏  举报