手撕代码系列之十个常用的数组方法js实现(代码片段)

余光、 余光、     2023-03-02     712

关键词:

【手撕代码系列】之十个常用的数组方法JS实现(一)

🚀 通俗易懂的实现方式,帮助我们认识相应的方法
📚 收藏本系列,基础进阶两不误
🎉 本系列持续更新,欢迎查看线上地址

写在前面

代码实现系列是与手写代码相关的第一个系列。
知识点总结的再多,也离不开思考和实践,否则就是空中楼阁,本系列顺序由浅至深。欢迎大家交流,探讨~

一、chunk

将数组(array)拆分成多个 size 长度的区块,并将这些区块组成一个新数组。 如果array 无法被分割成全部等长的区块,那么最后剩余的元素将组成一个区块。

1.1 参数

  • array (Array): 需要处理的数组
  • [size=1] (number): 每个数组区块的长度

1.2 返回

  • (Array): 返回一个包含拆分区块的新数组(注:相当于一个二维数组)。

1.3 实现

const _chunk = function (array, size = 1) 
    const length = array == null ? 0 : array.length;
    if (!length || size < 1) return [];

    const len = Math.ceil(length / size);
    const result = new Array(len);
    let index = -1;

    while (++index < len) 
        const start = size * index;
        result[index] = array.slice(start, size + start)
    
    return result;

1.4 测试

const arr = ['a', 'b', 'c', 'd']
_chunk(arr, 2);
// => [['a', 'b'], ['c', 'd']]
 
_chunk(arr, 3);
// => [['a', 'b', 'c'], ['d']]

二、concat

创建一个新数组,将array与任何数组值连接在一起。

2.1 参数

  • array (Array): 被连接的数组。
  • values: 连接的值。

2.2 返回值

  • (Array): 返回连接后的新数组。

2.3 实现

const _concat = function (array, ...values) 
    const result = [...array];
    values.forEach(val => 
        if (Array.isArray(val)) 
            result.push(...val);
         else 
            result.push(val);
        
    )
    return result;

2.4 测试

var array = [1];
var other = _concat(array, 2, [3], [[4]]);
 
console.log(other);
// => [1, 2, 3, [4]]
 
console.log(array);
// => [1]

三、difference

创建一个具有唯一array值的数组,每个值不包含在其他给定的数组中。返回过滤的新数组

3.1 参数

  • array (Array): 被过滤的数组。。
  • [values] (…Array): 排除的值。

3.2 返回值

  • (Array): 返回一个过滤值后的新数组。

3.3 实现

const _difference = (array, diff = []) => 
    if (!diff.length || !array.length) return [...array];

    return array.filter((val) => !diff.includes(val));
;

3.4 测试

_difference([3, 2, 1], [4, 2]);
// => [3, 1]

四、fill

使用 value 值来填充(替换) array,从start位置开始, 到end位置结束(但不包含end位置)。

注意: 这个方法会改变 array

4.1 参数

  • array (Array): 要填充改变的数组。
  • value (*): 填充给 array 的值。
  • [start=0] (number): 开始位置(默认0)。
  • [end=array.length] (number):结束位置(默认array.length)。

4.2 返回值

  • (Array): 返回 array。

4.3 实现

const _fill = (array = [], value, start = 0, end = array.length) => 
    const  length  = array;
    // 空数组
    if (!length) return array;
    // 边界
    const ends = end > length ? length : end;
    if (start > end) return array;

    for (let i = start; i < ends; i++) 
        array[i] = value;
    

    return array;
;

4.4 测试

const array = [1, 2, 3];
_fill(array, "a");
// => ['a', 'a', 'a']

_fill(Array(3), 2);
// => [2, 2, 2]

_fill([4, 6, 8, 10], "*", 1, 3);
// => [4, '*', '*', 10]

五、flattenDepth

按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

5.1 参数

  • depth(Number): 指定要提取嵌套数组的结构深度,默认值为 1。

5.2 返回值

  • (Any): 返回通过测试(函数内判断)的数组的第一个元素的值。

5.3 实现

// 余光
Array.prototype._flattenDepth = function (depth = 1) 
    // 获取调用者
    let arr = this;
    // 拍平层数校验
    if (depth < 1) return arr;

    return arr.reduce(
        (prev, next, i, n) => [
            ...prev,
            ...(Array.isArray(next) ? next._flattenDepth(depth - 1) : [next]),
        ],
        []
    );
;

5.4 测试

const res = [[1], [[2]]];
console.log(res.flat(1))
// => [1, [2]]
console.log(res.flat(2))
// => [1, 2]

六、join

将 array 中的所有元素转换为由 separator 分隔的字符串。

6.1 参数

  • array (Array): 要转换的数组。
  • [separator=’,’] (string): 分隔元素。

6.2 返回值

  • (string): 返回连接字符串。

6.3 实现

const _join = (array, separator = ",") => 
    return array.reduce((prev, next) => 
        return prev ? prev + separator + next : prev + next;
    , "");
;

6.4 测试

_join(['a', 'b', 'c'], '~');
// => 'a~b~c'

七、pop

删除数组的最后一个元素并返回删除的元素。

注意: 此方法改变数组的长度!

7.1 返回值

  • (any): 返回删除的元素。

7.2 实现

const _pop = function (array) 
    const result = array[array.length - 1];
    array.length - 1;
    return result;

7.3 测试

const sites = ['Google', 'Runoob', 'Taobao', 'Zhihu', 'Baidu'];
 
console.log(pop(sites));
// 输出结果为: "Baidu"
 
console.log(sites);
// 输出结果为: ['Google', 'Runoob', 'Taobao', 'Zhihu']

八、push

向数组末尾添加新项目,并返回新长度。

8.1 参数

  • array (Array): 要改动的数组
  • value1 … valueX: (必需)要添加的项目。

8.2 返回值

  • (Number): 返回数组的新长度。.

8.3 实现

const _push = function (array, ...params) 
    const len = array.length;
    for (let i = 0; i < params.length; i++) 
        array[len + i] = params[i]
    
    return array.length;
;

8.4 测试

const arr = [1, 2, 3];
_push(arr, 4);
console.log(arr)
// => [1, 2, 3, 4]

九、remove

移除数组中callback返回为真值的所有元素,并返回移除元素组成的数组。

注意: filter不同, 这个方法会改变数组 array。

9.1 参数

  • array (Array): 被连接的数组。
  • callback(function): 判断函数。

9.2 返回值

  • (Array): 返回移除元素组成的新数组。

9.3 实现

const _remove = function(array, callback) 
    const result = [];
    if (!(array != null && array.length)) 
        return result;
    
    const  length  = array;
    let i = -1;
    const ids = [];
    while (++i < length) 
        const value = array[i];
        if (callback(value, i, array)) 
            result.push(value);
        
    

    for (let i = 0; i < result.length; i++) 
        const index = array.indexOf(result[i]);
        array.splice(index, 1);
    
    return result;
;

9.4 测试

const array = [1, 2, 3, 4];
const evens = _remove(array, (n, i) => !(n % 2));

console.log(array);
// => [1, 3]

console.log(evens);
// => [2, 4]

十、reverse

反转array,使得第一个元素变为最后一个元素,第二个元素变为倒数第二个元素,依次类推。

注意: 这个方法会改变原数组 array,基于Array#reverse。

10.1 参数

  • array (Array): 要修改的数组。

10.2 返回

  • (Array): 返回 array.

10.3 实现

const _reverse = (array) => 
    for (let i = 0; i < Math.floor(array.length / 2); i++) 
        const left = i;
        const right = array.length - 1 - i;
        [array[left], array[right]] = [array[right], array[left]];
    
    return array;
;

10.4 测试

const array = [1, 2, 3];
 
_reverse(array);
 
console.log(array);
// => [3, 2, 1]

写在最后

本系列第一篇就到这里了,感兴趣的朋友可以留言讨论更好的代码实现,以及其他想了解的代码实现,下篇手撕代码系列会是其他数据类型相关的方法,收藏不走丢哦~

其他系列

值得收藏面试会用到的十个常用的数组方法js实现(代码片段)

【手撕代码系列】之十个常用的数组方法JS实现(一)🚀通俗易懂的实现方式,帮助我们认识相应的方法📚收藏本系列,基础进阶两不误🎉本系列持续更新,欢迎查看线上地址写在前面代码实现系... 查看详情

值得收藏面试会用到的七个常用的遍历方法js实现(代码片段)

【手撕代码系列】之7个常用的遍历方法JS实现(二)🚀通俗易懂的实现方式,帮助我们认识相应的方法📚收藏本系列,基础进阶两不误🎉本系列持续更新,欢迎查看线上地址写在前面代码实现系... 查看详情

值得收藏面试会用到的七个常用的遍历方法js实现(代码片段)

【手撕代码系列】之7个常用的遍历方法JS实现(二)🚀通俗易懂的实现方式,帮助我们认识相应的方法📚收藏本系列,基础进阶两不误🎉本系列持续更新,欢迎查看线上地址写在前面代码实现系... 查看详情

值得收藏面试会用到的七个常用的遍历方法js实现(代码片段)

【手撕代码系列】之7个常用的遍历方法JS实现(二)🚀通俗易懂的实现方式,帮助我们认识相应的方法📚收藏本系列,基础进阶两不误🎉本系列持续更新,欢迎查看线上地址写在前面代码实现系... 查看详情

迟早要知道的js系列之常用数组方法(代码片段)

常用数组方法一.不会改变原始数组的方法:即访问方法,下面的这些方法绝对不会改变调用它们的对象的值,只会返回一个新的数组或者返回一个其它的期望值。1.concat()**语法:**JavaScript,defaultvarnew_array=old_array.concat(value1[,value2[... 查看详情

javascript之手撕常用数组高阶函数(代码片段)

前言JavaScript中提供了一些高阶函数,例如map、filter、every等,还有ES6新提供的find等,熟练使用后能提高编写代码的效率。下面就一起来学习一下这些高阶函数,并使用原生JS模拟实现。那么什么样的函数是高阶函... 查看详情

js手撕promise2实现静态方法手撕asyncawaitgenerator(代码片段)

实现静态方法Promise.resolveallfinallyPromise.all方法接收一个promise的iterable类型,并且只返回一个Promise实例。如果全都成功它们的值就作为then的第一个参数的入参,为数组[val1,val2,],但是如果传入的promise中有一个失败(rejec... 查看详情

值得收藏面试会用到的七个常用的遍历方法js实现

【手撕代码系列】之7个常用的遍历方法JS实现(二)🚀通俗易懂的实现方式,帮助我们认识相应的方法📚收藏本系列,基础进阶两不误🎉本系列持续更新,欢迎查看线上地址写在前面代码实现系... 查看详情

手撕stlmap和set(代码片段)

map和setsetset的使用举例multisetmultiset的使用mapmultimapmultimap的使用红黑树模拟实现STL中的map与set红黑树的迭代器改造红黑树红黑树的代码(改装后)set的代码map的代码vector、list、deque……称为序列式容器——push系列pop系列ma... 查看详情

手撕stlmap和set(代码片段)

map和setsetset的使用举例multisetmultiset的使用mapmultimapmultimap的使用红黑树模拟实现STL中的map与set红黑树的迭代器改造红黑树红黑树的代码(改装后)set的代码map的代码vector、list、deque……称为序列式容器——push系列pop系列ma... 查看详情

数组常用的方法(代码片段)

https://www.w3school.com.cn/js/js_array_methods.asp JavaScript数组的力量隐藏在数组方法中。把数组转换为字符串JavaScript方法 toString() 把数组转换为数组值(逗号分隔)的字符串。实例varfruits=["Banana","Orange","Apple","Mango"];document 查看详情

前端面试题----手撕javascriptcallapplybind函数(超详细)(代码片段)

手撕JavaScriptcallapplybind函数文章目录手撕JavaScriptcallapplybind函数一、callapplybind函数的基本用法二、手写myCall方法ES6实现myCall方法ES5实现myCall方法三、手写myApply方法四、手写myBind方法一、callapplybind函数的基本用法  首先这三个... 查看详情

c/c++手撕哈希表详解(代码片段)

文章目录关于实现源码哈希表的理论知识哈希表的定义桶数组散列函数散列函数的构造扰动函数和按位与哈希冲突HashMap实现类型定义(键值对以及对应节点)哈希表的数据初始化方法(构造方法)根据散列函数得... 查看详情

前端日常开发常用功能系列之数组去重(代码片段)

这是前端日常开发常用功能这个系列文章的第一篇,该系列是日常开发中一些常用的功能的再总结、再提炼,以防止遗忘,便于日后复习。该系列预计包含以下内容:防抖、节流、去重、拷贝、最值、扁平、偏函数、柯里、惰性... 查看详情

手撕stlunordered_setunordered_map(用哈希表封装)(代码片段)

哈希unordered系列关联式容器unordered_mapunordered_map的接口说明unordered_setunordered系列关联式容器的使用底层结构哈希冲突常见哈希函数哈希冲突解决闭散列线性探测二次探测开散列开散列增容开散列与闭散列比较开散列的代码实现模... 查看详情

java方法的可变参数数组复制排序分类冒泡和选择排序搜索等常用方法实现(代码片段)

...组复制、排序分类、冒泡和选择排序等常用方法实现由于代码的可观性,下面分别以图片和文字形式展现:以下内容有些繁多,因为涉及内容过多,源代码也以两种形式贴上去了。①增强型for循环增强for循环-foreac... 查看详情

java——多线程高并发系列之reentrantlock实现(非)公平锁常用方法的举例(代码片段)

文章目录:写在前面Demo1(公平锁与非公平锁)Demo2(intgetHoldCount()返回当前线程调用lock()方法的次数)Demo3(intgetQueueLength()返回正等待获得锁的线程预估数)Demo4(intgetWaitQueueLength(Condition 查看详情

面试题之十亿条记录,怎么获取出现最多的前十个(代码片段)

...是我们来算成ip浏览记录吧。那么我们来获取10亿条ip 代码如下publicclasscreateIppublicstaticStringgetRandomIp()//ip范围int[][]range=607649792,608174079,//36.56.0.0-36.63.255.2551038614528,1039007743,//61.232.0.0-61.237.255.2551783627776,1784676351,//106.80.0.0-106.95.255.... 查看详情