目录
3.手写concat函数:concat(array,value)
4.手写difference函数:difference(array,value)
5.手写differenceBy函数:differenceBy(array,value,fn)
一.前言
1.什么是lodash
相信学前端的小伙伴应该对Lodash是比较了解的,Lodash是一个实用的 JavaScript 工具库,提供了很多常用的工具函数,以简化 JavaScript 编程。Lodash提供了许多对数组、数字、字符串和对象等进行操作的实用工具函数,这使得 JavaScript 开发更加高效、简便、可读、可维护。
Lodash的好处:
- 节省编程时间:通过提供封装好的优化的工具方法,减少编写各种常见代码的时间。
- 更加安全:通过 Lodash 提供的高抽象性 API,减少使用内置 JavaScript API 带来的人为失误的可能性。
- 更快的性能:Lodash 经过了严格的测试和针对不同环境的优化,性能要比自己实现的方法更高。
2.手写Lodash内置函数的好处
对于初学者而言,常常会因为学完Javascript和es6的语法却练手的地方而困扰,这样就容易造成学完就忘的情况,而原生Javascript对于前端学习者来说是非常重要的,如果没有打好基础以后就会造成很多问题,遇到问题很难独立解决,以及面试时要求手写一些底层原理代码等等,当你手写完Lodash内置函数后,你的基本功就会变得扎实,后续的学习也会变得豁然开朗。
二.今天的练习
1.手写chunk函数:chunk(array,size)
1.1:函数功能
将数组 array 拆分成多个 size 长度的区块,并将这些区块组成一个新数组。 如果 array无法被分割成全部等长的区块,那么最后剩余的元素将组成一个区块。
1.2:参数说明
array
(Array): 需要处理的数组
[size=1]
(number): 每个数组区块的长度
1.3:返回值
(Array): 返回一个包含拆分区块的新数组(注:相当于一个二维数组)。
1.4:实现代码
function check(array, size) {
// 如果需要划分的尺寸 size < 1,则直接返回空数组
if (size < 1) return []
const result = [] // 定义空数组,用于存放子数组
// 使用循环,每次将数组按照 size 切割成一个个子数组
for (let i = 0; i < array.length; i += size) {
// 使用 slice 函数截取一个子数组,并将其添加到结果数组中
result.push(array.slice(i, i + size))
}
return result
}
1.5:实现原理
利用了array的内置方法slice进行有位置的切割
1.6:测试用例
2.手写compact函数:compact(array)
2.1:函数功能
创建一个新数组,包含原数组中所有的非假值元素。例如false
, null
,0
, ""
, undefined
, 和 NaN
都是被认为是“假值”。
2.2:参数说明
array
(Array): 待处理的数组
2.3:返回值
(Array): 返回过滤掉假值的新数组。
2.4:实现代码
function compact(array) {
const result = []
if (array == null) return []
for (let i = 0; i < array.length; i++) {
if (array[i]) result.push(array[i])
}
return result
}
2.5:实现原理
先进判断数组是否为空,然后遍历加if判断,上述的“假值”都是过不了if判断的
2.6:测试用例
3.手写concat函数:concat(array,value)
3.1:函数功能
创建一个新数组,将array
与任何数组 或 值连接在一起。
3.2:参数说明
array
(Array): 被连接的数组。
[value]
(...*): 连接的值。
3.3:返回值
(Array): 返回连接后的新数组。
3.4:实现代码
function concat(...array) {
const result = []
for (let i = 0; i < array.length; i++) {
const arr = array[i]
if (Array.isArray(arr)) {
result.push(...arr) //这里使用的是es6的语法展开运算符
} else {
result.push(arr)
}
}
return result
}
3.5:实现原理
这里的参数也是利用了es6的语法,展开运算符来接收参数并将其放置一个数组中,而后就是进行遍历处理,如果是数组就将其扩展开放进原数组,否则就是直接push进原数组
3.6:测试用例
4.手写difference函数:difference(array,value)
4.1:函数功能
创建一个具有唯一array
值的数组,每个值不包含在其他给定的数组中。(注:即创建一个新数组,这个数组中的值,为第一个数字(array
参数)排除了给定数组中的值。)
4.2:参数说明
array
(Array): 要检查的数组。
[values]
(...Array): 排除的值。
4.3:返回值
(Array): 返回一个过滤值后的新数组。
4.4:实现代码
function difference(array, ...values) {
// 声明一个空数组,用于存放结果
const result = []
// 将所有 values 参数展开组成一个大数组
const valuesArray = []
for (let i = 0; i < values.length; i++) {
valuesArray.push(...values[i])
}
// 遍历 array 数组中的每个元素,判断是否在 valuesArray 数组中出现过
for (let j = 0; j < array.length; j++) {
// 在 valuesArray 中查找是否有与 array[j] 相等的元素
let hasEqual = false
for (let k = 0; k < valuesArray.length; k++) {
if (array[j] === valuesArray[k]) {
hasEqual = true
break
}
}
// 如果 array[j] 没有在任何 valuesArray 中出现过,则将其添加到 result 数组中
if (!hasEqual) {
result.push(array[j])
}
}
return result
}
4.5:实现原理
代码中加了详细注释
4.6:测试用例
5.手写differenceBy函数:differenceBy(array,value,fn)
5.1:函数功能
这个方法类似difference ,但是他加了一个限制,可以接收一个迭代器,类似于函数,但是那个参数也可以是字母,数组等,他根据fn的限制对前面的数组进行筛选
5.2:参数说明
array
(Array): 要检查的数组。
[values]
(...Array): 排除的值。
[fn]
(Array|Function|Object|string): fn调用每个元素。
5.3:返回值
(Array): 返回一个过滤值后的新数组。
5.4:实现代码
function differenceBy(arr1, arr2, iteratee) {
const func = typeof iteratee === 'function' ? iteratee : (obj) => obj[iteratee]
const values2 = new Set(arr2.map(func))
return arr1.filter((item) => !values2.has(func(item)))
}
5.5:实现原理
首先使用 map
方法将第二个数组中的元素转换并添加到 Set 对象中,然后使用 filter
方法过滤第一个数组中在 Set 对象中存在的元素,最终得到两个数组之间的差异。
map函数就是将数组以func传入的参数进行处理
例如:
const arr = ['hello', 'world', 'javascript'];
const newArr = arr.map(item => item.toUpperCase());
console.log(newArr); // ['HELLO', 'WORLD', 'JAVASCRIPT']
5.6:测试用例
坚持每天写五个,一段时间后,你的代码能力一定会突飞猛进的,加油