携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情
使用说明
lodash里的min方法是计算数组中的最小值。如果数组是空的或者假值将会返回undefined。
参数说明:参数只有一个,需要是数组类型。
_.min(1)
// => undefined
_.min(1,2)
// => undefined
_.min([]);
// => undefined
_.min([1])
// => 1
_.min([2,1,3])
// => 1
_.min([1,2,{},4])
// => 1
_.min([10,'a',{},4])
// => 4
_.min([99999,{}])
// => 99999
_.min({})
// => undefined
_.min(['a',{},])
// => {}
求指定数组的最小值
在之前的篇章中我们实现了max方法,同理,我们可以根据max的方法实现求指定数组的最小值。
对于指定数组,如果我们想要知道其最小值,那么就需要遍历每一个值,在每次遍历的时候去比较和存储,思路如下:
function getMinValue(array) {
if (!Array.isArray(array)) return undefined
const length = array.length;
let minValue = array[0]
for (let i = 1; i < length; i++) {
if (minValue > array[i]) {
minValue = array[i]
}
}
return minValue
}
我们发现获取指定数组最大值的方法与获取指定数组最小值的方法,代码逻辑是一样的,只是单纯的判断符号变了,我们甚至可以抽离出同样的代码逻辑在一个通用方法里:
function getLimitValue(type) {
if (!type) return () => { }
const gt = (param1, param2) => param1 < param2
const lt = (param1, param2) => param1 > param2
let getMethod = () => { }
if (type === 'max') {
getMethod = gt
}
if (type === 'min') {
getMethod = lt
}
return (array) => {
if (!Array.isArray(array)) return undefined
const length = array.length;
let result = array[0]
for (let i = 1; i < length; i++) {
if (getMethod(result, array[i])) {
result = array[i]
}
}
return result
}
}
const getMinValue = getLimitValue('min')
const getMaxValue = getLimitValue('max')
源码实现
我们知道,在max源码实现中借助了一个baseExtremum的工具库方法,从其语义知道是该方法是求极值的方法,并且我们也知道max和min差异性只是对比的符号不同。
在lodash源码里,baseExtremum正是对max方法和min方法通用逻辑的抽离,所以这便是baseExtremum方法第二个参数和第三个参数的意义。
在lodash的工具库里,两个值的比较被封装成了方法,第一个参数是否大于第二个参数的方法命名为baseGt,第一个参数是否小于第二个参数的方法命名为baseLt。
下面为lodash源码里min方法的实现:
function baseLt(value, other) {
return value < other;
}
function identity(value) {
return value;
}
function min(array) {
return (array && array.length)
? baseExtremum(array, identity, baseLt)
: undefined;
}
可见,min依旧是调用baseExtremum方法,max方法与min方法最大的区别就在于baseExtremum的第三个参数,即最值判断的逻辑处理。
小结
max方法不仅可以对数组进行操作,还可以对于字符串进行相应的比较操作。
同理min方法和max方法有相同的逻辑处理,两者的实现主要依托抽离封装的baseExtremum工具方法。
由于比较操作在后续的方法实现中具有通用性,所以lodash也抽离出比较操作方法baseGt和baseLt。