还在和难题搏斗中,今天总结三个不能再简单的题吧(肥宅挠头.jpg)
RGB转16进制
题目:创建一个函数,将传入的RGB十进制值转换为十六进制字符串,RGB有效值为0-255
,任何超出该范围的值都需要改为最近的有效值。
rgb(255, 255, 255) // 返回 FFFFFF
rgb(255, 255, 300) // 返回 FFFFFF
rgb(0,0,0) // 返回 000000
rgb(148, 0, 211) // 返回 9400D3
思路:
1.转换为十六进制字符串有简易方法:number.toString(16),具体运算方法这里就不写了(就是懒)。
2.计算结果如果只有一位,需要在前面补0,如rgb(0,0,1) 需要得到 "000001" ,而不能是 "001"。
3.输入值小于0时直接返回 "00" ,超过255时直接返回 "ff" 。
了解这些点之后就可以开工了,这里直接使用三目运算符及ES6模板字符串,大大缩短代码长度:
function rgb(r, g, b){
let r16 = `${r<=0?'00':r>=255?'ff':r.toString(16)}`.length === 1?`0${r<=0?'00':r>=255?'ff':r.toString(16)}`:`${r<=0?'00':r>=255?'ff':r.toString(16)}`
let g16 = `${g<=0?'00':g>=255?'ff':g.toString(16)}`.length === 1?`0${g<=0?'00':g>=255?'ff':g.toString(16)}`:`${g<=0?'00':g>=255?'ff':g.toString(16)}`
let b16 = `${b<=0?'00':b>=255?'ff':b.toString(16)}`.length === 1?`0${b<=0?'00':b>=255?'ff':b.toString(16)}`:`${b<=0?'00':b>=255?'ff':b.toString(16)}`
return `${r16}${g16}${b16}`.toUpperCase()
}
可以用但太丑了,我们将一样的部分抽出一个函数:
function rgb(r, g, b){
function hex(num){
return `${num<=0?'00':num>=255?'ff':num.toString(16)}`.length === 1?`0${num<=0?'00':num>=255?'ff':num.toString(16)}`:`${num<=0?'00':num>=255?'ff':num.toString(16)}`
}
return `${hex(r)}${hex(g)}${hex(b)}`.toUpperCase()
}
好看一些了,但hex返回值过长,不够一目了然。我们将hex中重复的内容提成变量:
function rgb(r, g, b){
function hex(num){
let result = num<=0?'00':num>=255?'ff':num.toString(16)
return result.length === 1?`0${result}`:result
}
return `${hex(r)}${hex(g)}${hex(b)}`.toUpperCase()
}
这样就简单美观了,也比较方便阅读。
diff
题目:实现一个差函数,该函数接收两个数组,并且返回两个数组的差值(即从数组1中删除数组2中出现的所有值,并保持数组1的顺序不变)
arrayDiff([1,2],[1]) == [2]
arrayDiff([1,2,2,2,3],[2]) == [1,3]
思路:
1. 遍历两个数组,若数组1中有值与数组2中相同,则删除数组1中的该值。
2. 完成删除后,数组1长度发生变化,所以需要重新遍历数组1,这里选择使用递归。
3. 删除完毕之后返回数组1的值。
function arrayDiff(a,b){
function diff(a,b){
if(a.length !== 0){
for(let i in a){
for(let j in b){
if(a[i] === b[j]){
// 删除 a 与 b 中某一项相等的项
a.splice(i,1)
// 下标变更,不能继续遍历了,重新执行diff
diff(a,b)
}
}
}
// a 数组遍历完成后走到这里,此时证明diff已经完成了
// 返回 a 数组的值作为结果
return a
}
}
return diff(a,b)
}
这里的遍历使用了最基础的for循环,代码更繁琐。
遍历数组的方法很多,选择合适的方法即可(虽然我总是因为记不住又懒得搜导致for循环一把梭)
将秒转换为可读的时分秒格式
题目:创建一个函数,传入一个非负整数(秒),得到一个可读格式的返回时间HH:MM:SS
(小时数固定为两位数,范围为00-99
)
思路:
- 这个题只有一个需要思考的地方:如何通过秒得到时分秒三个值,这里需要善用取余数:“%”运算符。
- 将秒除以3600,可以得到小时数,而它的余数便是剩余的分钟数且它的值绝对不会大于60分钟。
- 同理,用上面得到的余数除以60可以得到分钟数,且余数为秒并且绝对不会大于60秒。
- 分别求出时分秒后拼接即可。
function humanReadable(seconds) {
let h =String(seconds/3600)
let m = String(seconds%3600/60)
let s = String(seconds%3600%60)
function getTime(time){
// 若得数小于 10 ,需要在前面补 0
return time.split('.')[0].length===2?`${time[0]}${time[1]}`:`0${time[0]}`
}
// 分别求值后拼接即可
return `${getTime(h)}:${getTime(m)}:${getTime(s)}`
}