美文网首页
手动实现Javascript数组的常用方法

手动实现Javascript数组的常用方法

作者: 尤小小 | 来源:发表于2018-12-28 14:34 被阅读6次

闲来无事将数组的常用方法实现了一遍,并没有想象的那么难,注意好临界情况,和特殊值的处理就好了,其中splice()方法是实现上最复杂的一个。建议前端开发者可以将splice()手动实现一遍,会有意想不到的收获。在思考的过程中可以讲相似方法,通过传不同的参数提取为公共方法。

查找元素

indexOf()

用来查找传进来的参数在目标数组中是否存在,没有找到返回-1

手动实现:

{
    function arrIndexOfHandle(arr, item) {
        let index = -1;
    
        for (let i = 0; i < arr.length; i++) {
            if (arr[i] === item) {
                return index = i // 找到目标元素,立即返回元素的序列号,终止循环
            }
        }
    
        return index
    }
    
    let arr = ['gao', 'bing', 1, 3, 23, 'gao'];
    
    console.log(arrIndexOfHandle(arr, 'gao')) // 0
    console.log(arrIndexOfHandle(arr, 3)) // 3
    console.log(arrIndexOfHandle(arr, 33)) // -1
}

lastIndexOf()

返回相同元素中最后一个元素的索引,没有找到返回-1

{
    function arrLastIndexOfHandle(arr, item) {
        let index = -1;
        let LEN = arr.length;
    
        for (var i = LEN; i >= 0; i--) {
            
            if (arr[i] === item) {
                index = i
                return index //  倒序对比的时候,找到目标元素,就返回元素的序列号,终止循环
            }
        }
    
        return index
    }
    
    let arr = ['gao', 'bing', 1, 3, 23, 'gao', 3];
    
    console.log('gao:' + arrLastIndexOfHandle(arr, 'gao')) // 5
    console.log('3:' + arrLastIndexOfHandle(arr, 3)) // 6
    console.log('33:' + arrLastIndexOfHandle(arr, 33)) // -1
}

indexOf和lastIndexOf方法有很多重复的部分,如何精简提取公共部分。

{
    function creatIndexHandle(dir, arr, item) {
        
        let LEN = arr.length;
        let index = dir > 0 ? 0 : LEN - 1;

        for (; index >= 0 && index < LEN; index += dir) {

            if (arr[index] === item) {
                return index 
            }
        }

        return -1
    }
    
    
    function arrIndexOfHandle(arr, item) {
        return creatIndexHandle(1, arr, item)
    }

    var arr1 = ['gao', 'bing', 1, 3, 23, 'gao'];

    console.log(arrIndexOfHandle(arr1, 'gao')) // 0
    console.log(arrIndexOfHandle(arr1, 3)) // 3
    console.log(arrIndexOfHandle(arr1, 33)) // -1


    function arrLastIndexOfHandle(arr, item) {
        return creatIndexHandle(-1, arr, item)
    }

    var arr = ['gao', 'bing', 1, 3, 23, 'gao', 3];

    console.log('gao:' + arrLastIndexOfHandle(arr2, 'gao')) // 5
    console.log('3:' + arrLastIndexOfHandle(arr2, 3)) // 6
    console.log('33:' + arrLastIndexOfHandle(arr2, 33)) // -1
}

数组转化为字符串

join()

返回一个包含数组所有元素的字符串,各元素之间用逗号分隔开

{
    function arrJoinHandle(arr, str) {
        let index = -1;
        let LEN = arr.length;
        let arrStr = '';
        if (str == undefined) str = ',' // join 方法接受一个参数的时候,默认通过逗号来进行连接,在这里进行特殊处理
    
        for (var i = 0; i < LEN; i++) {
            arrStr += arr[i] + str;
        }
    
        return arrStr
    }
    
    let arr = ['gao', 'bing', 1, 3, 23, 'gao', 3, 0, '', ' '];
    
    console.log(arrJoinHandle(arr)) // gao,bing,1,3,23,gao,3,0,, ,
    console.log(arrJoinHandle(arr, '')) // 
    VM122393:16 gaobing1323gao30 
    console.log(arrJoinHandle(arr, '|')) // gao|bing|1|3|23|gao|3|0|| |
}

toString()

toString方法通json方法类似,返回一个包含数组所有元素的字符串,各元素之间用逗号分割开。但是toString不接收第二个参数,当传第二个参数的时候,toString方法默认不处理。

{
    function arrToStringHandle(arr) {
        let index = -1;
        let LEN = arr.length;
        let arrStr = '';
    
        for (var i = 0; i < LEN; i++) {
            arrStr += arr[i] + ',';
        }
    
        return arrStr
    }
    
    let arr = ['gao', 'bing', 1, 3, 23, 'gao', 3, 0, '', ' '];
    
    console.log(arrToStringHandle(arr)) // gao,bing,1,3,23,gao,3,0,, ,
    console.log(arrToStringHandle(arr, '')) // gao,bing,1,3,23,gao,3,0,, ,
    console.log(arrToStringHandle(arr, '|')) // gao,bing,1,3,23,gao,3,0,, ,
}

创建新数组

concat()

合并数组:发起者是一个数组,参数是另外一个数组,作为参数的数组;不改变原数组;

{
    function arrContatHandle(arrFirst, arrSecond) {
        let arrFirstLEN = arrFirst.length;
    
        for (var i = 0; i < arrSecond.length; i++) {
            arrFirst[arrFirstLEN] = arrSecond[i]; // 在插入数据的时候 不能使用push方法,这样我就需要每次插入的时候都得确认插入的位置,每次循环更新插入的位置
            arrFirstLEN++;
        }
    
        return arrFirst
    }
    
    let arr1 = ['gao', 'bing', 1, 3];
    let arr2 = [23, 'gao', 3, 0, '', ' '];
    let arr3 = ['23', 'bing', ' '];
    
    console.log(arrContatHandle(arr1, arr2)) //  ["gao", "bing", 1, 3, 23, "gao", 3, 0, "", " "]
    console.log(arrContatHandle(arr3, arr2)) // ["23", "bing", " ", 23, "gao", 3, 0, "", " "]
}

* splice()

会改变原数组,返回一个新数组;接受多个参数,第一个截取的开始索引,第二个是截取的长度,第三、四是要插入的元素。

{
    function arrSpliceHandle() {
            
        let args = arguments
        let arr = args[0] ? args[0] : [] // 原数组
        let startIndex = args[1] ? args[1] : 0 // 截取起始位置
        let deleteNum = args[2] ? args[2] : 0 // 要删除元素的个数
        let arrLEN = arr.length;

        // splice 只有一个参数的时,代表从该起始位置到数组的最后一个元素,返回截取到的数组,会更改原数组
        if (args.length == 2) {
            if (startIndex < arrLEN) {
                arr.length = startIndex
            } 
            return arr
        }

        // splice 两个参数时,代表从该起始位置开始截取,截取固定的几位,返回截取到的数组,这里需要考虑开始截取的位置的临界值,和要截取个数的临界值
        if (args.length == 3) {
            if (startIndex < arrLEN && startIndex + deleteNum >= arrLEN) {
                arr.length = startIndex
                return arr 

            } else if (startIndex < arrLEN && startIndex + deleteNum < arrLEN) {
                let newArr = []
                let newArrIndex = 0;
                
                for (var i = 0; i < arrLEN; i++) {
                    if (i < startIndex) {
                        newArr[newArrIndex] = arr[i]
                        newArrIndex++
                    }

                    if (i > startIndex + deleteNum - 1) {
                        newArr[newArrIndex] = arr[i]
                        newArrIndex++
                    }
                }
                return newArr
            }
        }

        // splice 三个参数时,代表从该起始位置开始截取,截取几位,再添加几位元素;这里除了需要考虑开始截取的位置的临界值,和要截取个数的临界值,还需要考虑插入的元素起始位置,和结束位置,以及后面的元素需要向后移动。
        if (args.length > 3) {
            if (startIndex < arrLEN && startIndex + deleteNum >= arrLEN) {
                arr.length = startIndex
                return concatArrHandle(arr)

            } else if (startIndex < arrLEN && startIndex + deleteNum < arrLEN) {
                let newArr = []
                let newArrIndex = 0;

                for (var i = 0; i < arrLEN; i++) {
                    if (i < startIndex) {
                        newArr[newArrIndex] = arr[i]
                        newArrIndex++
                    }

                    if (i > startIndex + deleteNum - 1) {
                        newArr[newArrIndex] = arr[i]
                        newArrIndex++
                    }
                }

                return concatArrHandle(newArr)
            }
        }

        function concatArrHandle(tempArr) {
            let tempArrLEN = tempArr.length
            for (let j = 3; j < args.length; j++) {
                tempArr[tempArrLEN] = args[j]
                tempArrLEN++
            }

            return tempArr
        }

        return arr 
    }

    let arr1 = ['gao', 'bing', 1, 3]
    let arr2 = ['gao', 'bing', 1, 3]
    let arr3 = ['gao', 'bing', 1, 3]
    let arr4 = ['gao', 'bing', 1, 3]
    let arr5 = ['gao', 'bing', 1, 3]

    console.log(arrSpliceHandle(arr1, 0)) //  []
    console.log(arrSpliceHandle(arr2, 0, 6)) //  []
    console.log(arrSpliceHandle(arr3, 2, 6)) //  ["gao", "bing"]
    console.log(arrSpliceHandle(arr4, 1, 2)) //  ["gao", 3]
    console.log(arrSpliceHandle(arr5, 1, 2, 'yan', 'gaoxiaohei', 'gaoheihei')) //  ["gao", 3, "yan", "gaoxiaohei", 
}

为数组添加元素

push() 将一个元素(多个元素)添加到数组末尾

{
    function arrPushHandle() {
        let args = arguments; // 接收参数
        let argsLEN = arguments.length // 参数的长度
        let arr = arguments[0] // 要加入元素的数组
        let arrLEN = arr.length // 要加入元素的数组的长度
    
        for (var i = 1; i < argsLEN; i++) {
            arr[arrLEN] = args[i]
            arrLEN++
        }
        return arr
    }
    
    let arr1 = ['gao', 'bing', 1, 3];
    let arr2 = ['gao', 'bing', 1, 3];
    let arr3 = ['gao', 'bing', 1, 3];
    
    console.log(arrPushHandle(arr1, 2)) //  ["gao", "bing", 1, 3, 2]
    console.log(arrPushHandle(arr2, 'gaoheihei')) //  ["gao", "bing", 1, 3, "gaoheihei"]
    console.log(arrPushHandle(arr3, 2, 'gaoheihei')) //  ["gao", "bing", 1, 3, 2, "gaoheihei"]
}

unshift() 将一个元素(多个元素)添加数组的开头

{
    function arrUnshiftHandle() {
        let args = arguments; // 接收参数
        let argsLEN = args.length // 参数的长度
        let arr = args[0] // 要加入元素的数组
        let arrLEN = arr.length // 要加入元素的数组的长度
    
        // 元素后移
        for (var i = arrLEN; i >= 0; i--) {
            arr[i + argsLEN - 2] = arr[i - 1]
        }
    
        // 插入新元素
        let addIndex = 0;
        for(let j = 1; j < argsLEN; j++ ) {
            arr[addIndex] = args[j]
            addIndex++
        }
        return arr
    }
    
    let arr1 = ['gao', 'bing', 1, 3];
    let arr2 = ['gao', 'bing', 1, 3];
    let arr3 = ['gao', 'bing', 1, 3];
    
    console.log(arrUnshiftHandle(arr1, 2)) //  [2, "gao", "bing", 1, 3]
    console.log(arrUnshiftHandle(arr2, 'gaoheihei')) //  ["gaoheihei", "gao", "bing", 1, 3]
    console.log(arrUnshiftHandle(arr3, 2, 'gaoheihei')) //  [2, "gaoheihei", "gao", "bing", 1, 3]
}

新的数组添加进来后,需要将后面的每个元素都相应地向后移一个位置

为数组删除元素

pop() 将一个元素从数组末尾删除

不接受传参

{
    function arrPopHandle(arr) {
        if (arr.length > 0) { // 空数组,数组长度不减1
            arr.length = arr.length - 1
        }
        
        return arr
    }
    
    let arr1 = ['gao', 'bing', 1, 3]
    let arr2 = ['gao', 'bing', 1]
    let arr3 = []
    
    console.log(arrPopHandle(arr1)) //  ["gao", "bing", 1]
    console.log(arrPopHandle(arr2)) //  ["gao", "bing"]
    console.log(arrPopHandle(arr3)) //  []
}

shift() 将一个元素从数组的开头删除

{
    function arrShiftHandle(arr) {
        let LEN = arr.length;
    
        for (var i = 0; i < LEN; i++) {
            arr[i] = arr[i+1]
        }
        
        if (LEN > 1) { // 处理空数组 极限情况,若不是空数组,数组长度-1
            arr.length = arr.length - 1
        }
        return arr
    }
    
    let arr1 = ['gao', 'bing', 1, 3]
    let arr2 = ['gao', 'bing', 1]
    let arr3 = []
    
    console.log(arrShiftHandle(arr1)) //  ["bing", 1, 3]
    console.log(arrShiftHandle(arr2)) //  ["bing", 1]
    console.log(arrShiftHandle(arr3)) //  []
}

头部删除了元素,并没有改变数组的长度,需要重置数组的长度

为数组排序

reverse()

该方法将数组中元素的顺序进行翻转

{
    function arrReverseHandle(arr) {

        let LEN = arr.length
        let newArr = []

        for(var i = 0; i < arr.length; i++) {
            newArr[LEN - 1] = arr[i]
            LEN--
        }
        return newArr
    }

    let arr1 = ['gao', 'bing', 1, 3]
    let arr2 = ['gao', 'bing', 1]
    let arr3 = []

    console.log(arrReverseHandle(arr1)) //  [3, 1, "bing", "gao"]
    console.log(arrReverseHandle(arr2)) //  [1, "bing", "gao"]
    console.log(arrReverseHandle(arr3)) //  []
}

sort()

按照字典顺序对元素排序


相关文章

网友评论

      本文标题:手动实现Javascript数组的常用方法

      本文链接:https://www.haomeiwen.com/subject/rcgslqtx.html