最近发现对于 JavaScript 中数组的方法有些忘记了,借助这个算法题回忆一波。
因为主要是为了回忆知识点,所以时间复杂度和空间复杂度不是主要的考虑因素。
题目用大白话讲就是:给个数组,数组里有两个数,需求是求两者之间所有数字的和。
eg:
sumAll([1, 4]) => 1+2+3+4 = 10
sumAll([4, 1]) => 1+2+3+4 = 10
sumAll([5, 10]) => 5+6+7+8+9+10 = 45
sumAll([10, 5]) => 5+6+7+8+9+10 = 45
这个函数吃的是数组,挤出来的是数字间的和。
1. 统一入参格式
输入是数组,数组中含有两个数字元素,且两者的大小不定。
那么我们的第一个工作也就出来了。
如何对数组进行排序?
排序是算法里的基本操作,冒泡等都是可以的,但 JavaScript 作为高级语言,大可不必 for 循环,有函数专门来做。
对数组排序的法子很多,这里使用高阶方法 sort
演示。
// 数组已经原地进行了排序,无需进行复制,即改变原数组
arr.sort((a, b) => a - b)
//a, b 是将要比较的两个值,如果回调的值<0 a会跑到前面
// 有点绕。。。
// 所以逆序是下面的
arr.sort((a, b) => b - a)
sort() 内部使用的是原地算法,不要问我什么是原地算法,我不知道。
这个 sort
有点意思,如果没有指定函数,那么比较的依据是 Unicode 位点。
这里还有编码的知识。
那么如何知道一个数字对应的Unicode呢?有空填坑。
sort() 不但可以对数字进行排序,对于对象的 key 也是可以排序的。
这里涉及到类型转换,下次一定。
2. 生成数组
好的,现在我们对输入数据进行了格式化即正序排列的数组,接下来将两者之间的数字填充完好。
// 根据头和尾生成中间数字组成的数组
function generArr(arr) {
// 不废话,for in 遍历
let gArr = []
for(let i = arr[0]; i <= arr[1]; i++) {
gArr.push(i)
}
return gArr
}
const arr = generArr([1, 4])
console.log(arr)
3. 求和
下面是求和,求和有很多种方法,明显,这是一个等差数列,可以直接使用公式。
但有点不具有普遍性,如果下次遇到的等差数列的 d 值改变,可能就需要再考虑。
这里可以将其抽象成任意数组的求和问题。
// 数组求和,使用高阶函数reduce
const result = arr.reduce((acc, cur) => acc + cur)
// reduce 吃的是数组,吐出来的是一个数字
console.log(result)
举一反三,求数组元素的积也是可以的。
arr.reduce((acc, curr) => acc * cur)
reduce 的用处不止于此,你甚至可以使用它进行数组扁平化,将二维数组变成一维数组,数组扁平化是个重点,下次一定。
统计词频也是可以的,你甚至可以用它进行数组去重操作。
总结
- 通过数组
sort
方法对数组进行排序,虽然只有两个元素。 - 使用普通的
for in
遍历,补全数组。 - 使用数组
reduce
方法对数组求和。
从中我们可以搞到单元操作:数组排序,生成指定区间的数组,数组求和。
还有地方可以补充,比如 sort
对原数组进行了更改,那么如果要在保证原数组不变的情况下,如何对数组进行排序?生成数组时采用了 for in
,有没有可能使用高阶函数?
一道题复习了两个高阶函数 sort
和 reduce
。
下面是完整的代码:
function sumAll(arr) {
arr.sort((a, b) => a - b)
let gArr = []
for (let i = arr[0]; i <= arr[1]; i++) {
gArr.push(i)
}
const result = gArr.reduce((acc, cur) => acc + cur)
console.log(result)
return result
}
sumAll([1, 4])
sumAll([4, 1])
网友评论