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

闲来无事将数组的常用方法实现了一遍,并没有想象的那么难,注意好临界情况,和特殊值的处理就好了,其中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()

按照字典顺序对元素排序


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • 首先给大家介绍javascript jquery中定义数组与操作的相关知识,具体内容如下所示: 1.认识数组 数组...
    JamHsiao_aaa4阅读 1,894评论 0 2
  • 数组总共有22种方法,本文将其分为对象继承方法、数组转换方法、栈和队列方法、数组排序方法、数组拼接方法、创建子数组...
    Sachie阅读 879评论 0 7
  • 转载:在开发中,数组的使用场景非常多,平日中也涉及到很多数组的api/相关操作,一直也没有对这块内容进行一块整理总...
    七色烟火阅读 3,207评论 0 3
  • Javascript有很多数组的方法,有的人有W3C的API,还可以去MDN上去找,但是我觉得API上说的不全,M...
    顽皮的雪狐七七阅读 4,062评论 0 6
  • 主动,不持外力推动而行动,能够造成有利局面,使事情按照自己的意图进行。 刚开始是什么让我变得主动,是压力,是这个吃...
    船长Fcou阅读 135评论 1 1