zoukankan      html  css  js  c++  java
  • JS对象类型数组方法篇

    继承方法

    继承自对象的方法有三种:toString()、toLocaleString()和valueOf()

    toString()

    toString()方法返回数组中元素以逗号分隔的字符串。同不传参的join()方法表现效果一样。

    [1,2,3].toString() // '1,2,3'
    [1,2,3].join() // '1,2,3'
    

    toLocaleString()

    toLocaleString()方法是toString()方法的本地化版本,经常返回相同的值。

    [1,2,3].toLocaleString() // '1,2,3'
    

    如果某一项值是nullundefined,那么使用toLocaleString()或toString()方法返回值以空字符表示

    [1,null,undefined, 2].toString() // '1,,,2'
    [1,null,undefined, 2].toLocaleString() // '1,,,2'
    

    valueOf()

    valueOf()方法返回数组本身

    [1,2,3].valueOf()  // [1,2,3]
    

    转换方法

    join()方法把数组转换为字符串,它是String.split()方法的逆向操作,split()是将字符串切割成数组。

    join()方法接受一个参数,表示用作分隔符的字符串。

    // 默认使用逗号分隔符
    [1,2,3].join() // '1,2,3'
    
    // 不使用分隔符
    [1,2,3].join('') // '123'
    
    // 空格作为分隔符
    [1,2,3].join(' ') // '1 2 3'
    
    

    实现字符串重复效果

    function repeatString(str, n) {
      return new Array(n + 1).join(str)
    }
    
    repeatString('hi', 3) // 'hihihi'
    

    类数组对象也可以使用join()方法

    var arrLike = {0: 'a', 1: 'b', 2: 'c', length: 3}
    Array.prototype.join.call(arrLike, '-') // 'a-b-c'
    

    栈和队列方法

    栈是一种LIFO(Last-In-First-Out,后进先出)的数据结构,最新添加的项会最先被移除。栈中项的插入(又称推入)和移除(又称弹出)均发生在栈的顶部。JS提供了push()和pop()方法实现了类似栈的行为。

    队列是一种FIFO(First-In-First-Out,先进先出)的数据结构,最先添加的项最先被移除。队列中项的插入和移除均发生在列表的底部。JS提供了unshift()和shift()方法实现了类似队列的行为。

    push()

    push()方法接收任何数量的参数,把它们添加到数组的末尾,返回修改后的数组长度。该操作改变原始数组。

    var a = []
    console.log(a, a.push('a','b','c')) // ['a','b','c'] 3
    
    console.log(a, a.push(['d','e'])) // ['a','b','c',['d','e']] 4
    

    push()方法也可以向对象中添加元素,对象会变成类数组对象。

    var o = {name: 'hello'}
    console.log(o, [].push.call(o, 'a', 'b')) // {0: "a", 1: "b", name: "hello", length: 2}
    

    pop()

    pop()方法从数组末尾移除最后一项,返回移除项。该操作改变原始数组。

    var a = ['a', 'b', 'c']
    console.log(a,a.pop()); // ['a', 'b'] 'c'
    
    var a2 = []
    console.log(a2,a2.pop()) // [] undefined
    

    unshift()

    unshift()方法接收任何数量的参数,把它们添加到数组的前端,返回修改后的数组长度。该操作改变原始数组。

    var a = ['a', 'b', 'c']
    console.log(a,a.unshift('x','y','z')) //['x','y','z','a', 'b', 'c'] 6
    

    当有多个参数时,参数是一次向插入的,所以插入元素的顺序和参数的顺序一致。

    shift()

    shift()方法移除数组中的第一项,返回移除项。该操作改变原始数组。

    var a = ['a','b','c']
    console.log(a,a.shift()); // ['b', 'c'] 'a'
    
    var a2 = []
    console.log(a2,a2.shift()) // [] undefined
    

    排序方法

    数组中有sort()和reverse()两个排序方法,它们均改变原始数组

    reverse()

    reverse()方法反转原始数组的顺序,返回排序后的数组。

    var arr = [1,2,3]
    console.log(arr,arr.reverse()) // [3,2,1] [3,2,1]
    

    sort()

    sort()方法默认情况下按字符串升序排列数组项,每个数组项会调用toString()方法,通过比较得到的字符串进行排序,返回排序后的数组。

    var a = [1,4,2,3]
    console.log(a, a.sort()) // [1,2,3,4]
    

    sort()方法接收一个函数作为参数,可以指定哪个值在哪个值前。函数接收两个参数,如果第一个参数应该位于第二个参数之前则返回一个负数,如果两个参数相等则返回0,如果第一个参数应该位于第二个参数之后则返回一个正数。

    function compare(value1,value2){
       // 字符串比较需要统一大小写,这里统一小写
        var v1 = value1.toLowerCase(); 
        var v2 = value2.toLowerCase();
        if(v1 < v2){
            return -1;
        }else if(v1 > v2){
            return 1;
        }else{
            return 0;
        }
    }
    var arr = ['pig','Cat','dog'];
    console.log(arr.sort(compare)); //  ["Cat", "dog", "pig"]
    
    

    数值类型或valueOf()方法返回数值类型的对象类型,可以简化比较函数

    function compare(value1,value2){
        return value1 - value2;
    }
    
    var arr = [5,1,3];
    console.log(arr.sort()); // [1, 3, 5]
    

    拼接方法

    concat()方法可以接收任意个数参数,它会把参数添加到数组的末尾。如果参数是数组,它会把数组中的每一项添加到数组的末尾。该操作创建一个数组的副本,所以不会改变原始数组。

    var a =[1,2,3]
    console.log(a,a.concat(4,[5,6], [[7,8]])) // [1, 2, 3]  [1, 2, 3, 4, 5, 6, [7,8]]
    

    如果不传递参数则返回一个数组的浅拷贝。
    浅拷贝是指如果数组中包含复合类型值(如对象、数组),那么新数组拷贝的是该值的引用。

    var a = [1,2]
    var newArr = a.concat()
    console.log(a,newArr) // [1,2] [1,2]
    
    a[0] = 0
    console.log(a,newArr) // [0,2] [1,2]
    
    
    var a2 = [1, {num: 2}]
    var newArr2 = a2.concat() 
    console.log(a2,newArr2) // [1, {num: 2}] [1, {num: 2}]
    
    a2[1].num = 3
    console.log(a2,newArr2) // [1, {num: 3}] [1, {num: 3}]
    

    concat()也可用于对象,把对象合并成数组

    var o = {name: 'hello', age: 10}
    
    console.log([].concat.call(o)) // [{name: "hello", age: 10}]
    

    创建子数组

    slice(start[,end])接收两个参数,返回字符串从start位置(不包括start位置处的字符)到end位置的一个子数组。如果end不存在,则end等于数组的长度值;如果start或end大于数组的长度,则start或end等于数组的长度。该操作不改变原始数组。

    如果start是负数,start = arr.length + start
    如果end是负数,end = arr.length + end

    var arr = [1,2,3,4,5]
    
    // 没有参数,返回原数组的浅拷贝
    arr.slice() // [1,2,3,4,5]
    
    arr.slice(2, 4) // [3,4]
    
    arr.slice(-2) // [4,5]
    
    

    slice()方法可用于类数组对象,把它变成数组

    Array.prototype.slice.call({ 0: 'a', 1: 'b', length: 2 })// ['a', 'b']
    

    数组删改

    splice()方法可以删改数组中的元素,并且可以在指定位置插入新的元素。该操作会改变原始数组。

    splice()方法的第一个参数start表示删除操作的起始位置,当值为负数时start等于length + start。第二个参数表示删除元素的个数,当值为负数时相当于0,值是0时不会删除元素。第二个参数之后的更多参数表示要插入到数组中的元素,插入位置由第一个参数决定。最终会返回一个由删除元素组成的数组。

    当只有一个参数时,会把数组在指定位置拆分成两个数组。

    var a = [1,2,3,4,5]
    console.log(a,a.splice()) // [1,2,3,4,5] []
    
    console.log(a,a.splice(3)) // [1,2,3]  [4,5]
    
    console.log(a,a.splice(-2)) // [1,2,3]  [4,5]
    

    第二个参数表示删除元素的个数

    var a = [1,2,3,4,5]
    
    console.log(a,a.splice(3, 1)) // [1,2,3,5] [4]
    console.log(a,a.splice(3, 0)) // [1,2,3,4,5] []
    

    第三个以及之后更多参数都表示要添加的项

    var a = [1,2,3,4,5]
    
    console.log(a,a.splice(3, 0,'a','b')) // [1, 2, 3, "a", "b", 4, 5]  []
    console.log(a,a.splice(3, 2,'a','b')) // [1, 2, 3, "a", "b"]  [4,5]
    

    位置查询方法

    ES5为数组实例增加了indexOf()和lastIndexOf()两个查询方法,

    indexOf()

    indexOf(search, start)方法接收两个参数,search表示搜索项,内部使用恒等运算符===进行比较。start表示搜索的起始位置,会自动调用Number()转型函数,当值为负数时start=length+start。该方法返回search首次出现的位置,如果找不到则返回-1。

    var arr = ['a','b','c','b','d']
    console.log(arr.indexOf('b')) // 1  a处(包含a)开始搜索
    console.log(arr.indexOf('b', 2)) // 3  c处(包含c)开始搜索
    console.log(arr.indexOf('b', -2)) // 3 第二个b处(包含b)开始搜索  5 + (-2) = 3
    console.log(arr.indexOf('e')) // -1
    

    lastIndexOf()

    lastIndexOf(search, start)方法同indexOf()方法类似,不同的是该方法是从右至左执行查询。

    var arr = ['a','b','c','b','d']
    console.log(arr.lastIndexOf('b')) // 3  d处(包含d)开始搜索
    console.log(arr.lastIndexOf('b', 2)) // 1 c处(包含c)开始搜索
    console.log(arr.lastIndexOf('b', -2)) // 3  第二个b处(包含b)开始搜索
    console.log(arr.lastIndexOf('e')) // -1
    

    注意: 字符串也有indexOf()和lastIndexOf()方法,但是当start为负数时,两则有区别:字符串的这两个方法会把start当做0,而数组的start等于length + start

    小技巧: 返回满足条件的所有索引项

    function allIndexOf(array,value){
        var result = [];
        var pos = array.indexOf(value);
        if(pos === -1){
            return -1;
        }
        while(pos > -1){
            result.push(pos);
            pos = array.indexOf(value,pos+1);
        }
        return result;
    }
    var array = ['a','b','c','b','d'];
    console.log(allIndexOf(array,'b'));//[1,3] 
    

    数组归并

    数组归并有reduce()和reduceRight()两个方法,它们均接受两个参数:第一个参数是函数,表示如何归并数组元素,它的任务就是使用某种方式把两个值组合成一个值,并返回组合后的值;第二个参数是可选的,表示传递给函数的初始化值。

    第一个参数是函数,函数有四个参数,前两个必选,后两个可选:

    1. 初始变量,默认为数组的第一个元素。函数执行一次后的返回值作为第二次执行的初始化变量,以此类推。
    2. 当前变量
    3. 当前变量在数组中的索引
    4. 原始数组对象
    values.reduce(function(prev, cur, index, array){
       //todo
    });
    

    第二个参数是传递给函数的初始化值。

    var a = [1,2,3]
    // 求和
    var sum = a.reduce(function(prev, cur){ return prev + cur }, 0)
    // 求乘积
    var product = a.reduce(function(prev, cur){ return prev * cur }, 1)
    // 求最大值
    var max = a.reduce(function(prev, cur){ return (prev > cur) ? prev : cur })
    
    console.log(sum) // 6
    console.log(product) // 6
    console.log(max) // 3
    

    第二个参数的类型可以决定函数返回值的类型

    var a = [1,2,3]
    var sum = a.reduce(function(prev, cur){ 
        prev.sum = prev.sum + cur
        return prev
    }, {sum: 0})
    console.log(sum) // {sum: 6}
    

    注意: 在空数组上使用reduce()方法,如果没有初始化参数的话会导致类型错误。当数组只有一个值且没有初始化参数,或者数组为空且有一个初始化参数时,reduce()方法只会返回那个值而不会调用函数。

    var a = []
    var sum = a.reduce(function(prev, cur){ return prev + cur }) // 报错
    var sum2 = a.reduce(function(prev, cur){ return prev + cur }, 0) // 0
    
    var a2 = [0]
    var sum3 = a2.reduce(function(prev, cur){ return prev + cur }) // 0
    

    应用:找出数组中最长的元素

    var a = ['a', '123', 'ab', 'hello']
    var maxEle = a.reduce(function(prev, cur){
        return prev.length > cur.length ? prev : cur
    }, '')
    console.log(maxEle) // 'hello'
    

    应用:二维数组合并

    var a = [['a','b'], ['c','d']]
    var arr = a.reduce(function(prev, cur){
        return prev.concat(cur)
    })
    console.log(arr) // ["a", "b", "c", "d"]
    

    reduceRight()方法和reduce()方法类似,不同的是该方法是从高到低(右到左)处理数组。

    var a = [1,2,3]
    var sum = a.reduceRight(function(prev,cur){
        console.log(prev,cur)
        return prev + cur
    })
    
    console.log(sum)
    // 3 2
    // 5 1
    // 6
    

    迭代方法

    ES5为数组定义了5个迭代方法,每个方法都接收两个参数:第一个参数表示要在每一项上运行的函数;第二个参数是可选的,表示运行该函数的作用域对象,用于改变this值。第一个参数中的函数接收三个参数:数组项的值、该项的索引和数组对象本身。

    map()

    map()方法对数组中的每一项运行指定函数,最终返回一个由函数调用结果组成的数组

    var ret = [1,2,3].map(function(item, index, array) {
    return item * item
    })
    console.log(ret) // [1,4,9]
    
    // 第二个参数改变this指向
    var arr = ['a','b','c']
    var ret2 = [1,2].map(function(item, index, array){
        return this[item]
    }, arr)
    console.log(ret2) // ['b','c']
    

    日常开发中,该方法常用于获取对象数组中的指定属性

    var data = [{name: 'li', age: 10}, {name: 'wang', age: 15}, {name: 'zhang', age: 5}]
    var ret3 = data.map(function(item, index, array) {
    return item.name
    })
    console.log(ret3) // ["li", "wang", "zhang"]
    

    可以应用于类数组对象

    var str = 'hello'
    var ret = Array.prototype.map.call(str, function(item, index, arr) {
    return item.toUpperCase()
    })
    console.log(ret) // ["H", "E", "L", "L", "O"]
    

    稀疏数组中不存在的元素,不会调用该方法

    var arr = [1,,3]
    var ret = arr.map(function(item, index, arr){
        return item * 2
    })
    console.log(ret) // [2, empty, 6]
    

    forEach()

    forEach()方法对数组中的每一项运行指定函数,没有返回值。同使用for循环迭代数组效果一样。

    [1,2,3].forEach(function(item,index,arr){
        console.log(item)
    })
    // 1
    // 2
    // 3
    
    var arr = []
    [1,2,3].forEach(function(item, index, arr){
       this.push(item * item)
    }, arr)
    
    console.log(arr) // [1,4,9]
    

    对于多层嵌套的情况,this指向通常不一致,这时第二个参数很有用

    var obj = {
    name: 'wang',
    likes: ['音乐', '编程', '阅读'],
    test: function() {
        this.likes.forEach(function(item, index, arr){
        console.log(item)
        }, this)
      }
    }
    console.log(obj.test())
    // 音乐
    // 编程
    // 阅读
    

    forEach()循环可以用于类数组对象

    var str = 'abc'
    Array.prototype.forEach.call(str, function(item, index, array) {
      console.log(item)
    })
    //a
    //b
    //c
    

    对于稀疏数组中不存在的元素,forEach()方法不会调用该方法,而for循环照样遍历。

    var arr = [1,,3]
    for(var i = 0; i < arr.length; i++){
        console.log(arr[i])
    }
    // 1
    // undefined
    // 3
    
    arr.forEach(function(item, index, arr){
        console.log(item)
    })
    // 1
    // 3
    

    forEach()方法无法像for循环一样,在遍历过程中使用break语句终止遍历,会导致发生错误。

    var arr = [1,2,3]
    arr.forEach(function(item, index, arr){
        if(item === 2) break;
    })
    // Uncaught SyntaxError: Illegal break statement at Array.forEach
    

    filter()

    filter()方法对数组中的每一项运行指定函数,返回结果为true的项组成的数组。常用于筛选符合条件的数组项

    [1, 2, 3, 4, 5].filter(function (item, index, arr) {
      return item % 2 === 0
    }) // [2,4]
    
    var min = [3];
    var ret = [1, 2, 3, 4, 5].filter(function (item, index, arr) {
      return item > this[0]
    }, min);// 
    console.log(ret) // [4,5]
    

    稀疏数组中的空元素会被过滤掉。

    // 删除空缺、undefined和null元素
    var arr = [1,2,,3,undefined,null]
    var ret = arr.filter(function(item, index, arr){
        return item != undefined
    })
    console.log(ret) // [1,2,3]
    

    some()

    some()方法对数组中每一项运行指定函数,返回一个布尔值。当每项的执行结果都是false时才返回false,否则返回true。

    var arr = [1,2,3]
    arr.some(function(item, index, arr){
        return item > 2
    })
    // true
    

    every()

    every()方法对数组中每一项运行指定函数,返回一个布尔值。当每项的执行结果都是true时才返回true,否则返回false。

    var arr = [1,2,3]
    arr.every(function(item, index, arr){
        return item > 2
    })
    // false
    

    结语

    JavaScript中数组的方法是通用的,它们除了应用于数组外还可以应用于类数组对象。上面介绍的方法中除了toString()和toLocaleString()方法外,其他方法都是通用的。

    可以改变原始数组的方法有七个:push()、 pup()、 unshift()、 shift()、 sort()、 reverse()、 splice()。

    优秀文章首发于聚享小站,欢迎关注!
  • 相关阅读:
    vsprintf函数和va_list用法详解
    copy_from_user 详解
    OK6410之蜂鸣器buzzer字符驱
    树莓派调试PCF8591遇到的小问题
    APM关键姿态控制源码讲解
    APM姿态控制流程
    没有安装gawk
    git 第一次上传本地代码到远程仓库,解决 ! [rejected] master -> master (non-fast-forward)错误
    C++ 全面刨析使用指针方法 _new _delete
    typedef&define的用法与区别
  • 原文地址:https://www.cnblogs.com/yesyes/p/15351857.html
Copyright © 2011-2022 走看看