手撕代码系列之十个常用的数组方法JS实现
Posted 余光、
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手撕代码系列之十个常用的数组方法JS实现相关的知识,希望对你有一定的参考价值。
【手撕代码系列】之十个常用的数组方法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实现的主要内容,如果未能解决你的问题,请参考以下文章