1、arr.reduce详解
array.reduce(function (total, currentValue, currentIndex, arr), initialValue):
- initialValue为传递给回调函数的total初始值
- function中若干参数的解释如下:
- total: 初始值initialValue或上一次迭代时fun的返回值
- currentValue: 当前值
- currentIndex: 当前索引 => 可省略
- arr: 要累加的arr非空数组 => 可省略
注意: 当 initialValue 的值为空的,也就是没有初始值时,函数第一次累加的 total 将会是 arr 的第一个元素,此时currentindex 的值为 1。
2、数组中出现最多的元素
有一道算法题是这样的:让你编程找到数组中出现次数最多的元素, 该数组中的元素都为数字, 例如输入为[2, 2, 1, 1, 1, 2, 2], 输出为2。备注:这里假设次数最多的元素是存在的, 不需要讨论任何特殊情况。
无脑写法
无脑写法如下(时间复杂度O(n) 空间复杂度: O(n)):
const findMostElement = (arr) => {
// 遍历统计每个元素出现的次数
let temp = (new Array(arr.length)).fill(0);
arr.forEach((item) => {
temp[item] = temp[item] + 1;
});
// 找到出现最多的元素
let res = 0;
let count = 0;
for (let i = 0; i < temp.length; i++) {
if (temp[i] > count) {
count = temp[i];
res = i;
}
}
return res;
};
console.log(findMostElement([2, 2, 1, 1, 1, 2, 2])); // 2
console.log(findMostElement([2, 2, 2, 2, 2, 2, 2])); // 2
console.log(findMostElement([1, 2, 3, 4, 5, 6, 6])); // 6
基于arr.reduce的实现
JavaScript的数组有一个reduce方法, 可以对数组做迭代处理, 例如累加求和、计算每个元素出现的次数等。 下面是计算每个元素出现的次数的代码:
const names = ["Alice", "Bob", "Tiff", "Bruce", "Alice"];
const countedNames = names.reduce(function (allNames, name) {
if (name in allNames) {
allNames[name]++;
} else {
allNames[name] = 1;
}
return allNames;
}, {});
console.log(countedNames); // { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }
既然可以用arr.reduce计算出数组中每个元素出现的次数, 那么当然也可以由此得到下面的代码(查找数组中出现最多的元素):
const findMostElement = (arr) => {
let res = 0;
let count = 0;
arr.reduce(function (obj, currentValue) {
// console.log(obj);
obj[currentValue] ? obj[currentValue]++ : obj[currentValue] = 1;
if(obj[currentValue] > count) {
count = obj[currentValue];
res = currentValue;
}
return obj;
}, {});
return res;
};
console.log(findMostElement([2, 2, 1, 1, 1, 2, 2])); // 2
console.log(findMostElement([2, 2, 2, 2, 2, 2, 2])); // 2
console.log(findMostElement([1, 2, 3, 4, 5, 6, 6])); // 6
上述基于arr.reduce的代码的时间复杂度是O(n), 空间复杂度是O(k)(注意k为数组元素的种类)
3、其他关于arr.reduce的算法实现
当然肯定有比arr.reduce更好的写法来实现数组中出现次数最多的元素。arr.reduce更强大的一些用处在于: 数组去重、将二维数组转化为一维、将多维数组转化为一维等。
数组去重
let arr = [1,2,3,4,4,1]
let newArr = arr.reduce((pre,cur)=>{
if(!pre.includes(cur)){
return pre.concat(cur)
}else{
return pre
}
},[])
console.log(newArr);// [1, 2, 3, 4]
将二维数组转化为一维
const arr = [
[0, 1],
[2, 3],
[4, 5],
];
const newArr = function (arr) {
return arr.reduce((pre, cur) => pre.concat(cur), []);
};
console.log(newArr(arr)); //[0,1,2,3,4,5]
将多维数组转化为一维
const arr = [
[0, 1],
[2, 3],
[4, [5, 6, 7]],
];
const newArr = function (arr) {
return arr.reduce(
(pre, cur) => pre.concat(Array.isArray(cur) ? newArr(cur) : cur),
[]
);
};
console.log(newArr(arr)); //[0, 1, 2, 3, 4, 5, 6, 7]
注意: 箭头函数里面当只有一条语句且没有大括号的时候可以省略return