array.reduce((previousValue,currentValue,currentIndex,array)=>{},initialValue)
对数组累计执行回调函数并返回最终结果
// 不设置初始值initialValue时
let result1 = arr.reduce((previousValue,currentValue,arr) => {
console.log(previousValue,"previousValue ============");
console.log(currentValue,"currentValue ============");
return previousValue + currentValue
})
console.log(result1); // 15
// 设置初始值initialValue时
let initialValue = 0
let result2 = arr.reduce((previousValue,currentValue,arr) => {
console.log(previousValue,"previousValue ============");
console.log(currentValue,"currentValue ============");
return previousValue + currentValue
},initialValue)
console.log(result2); // 15
let arr = [
[20,30,20,10,32],
[21,20,24,19,92],
[20,43,20,20,32],
[70,30,29,10,12],
]
let result = arr.reduce((previousValue,currentValue) => {
return previousValue.concat(currentValue)
},[])
console.log(result);
const arr = [
"a", "b", "a",, "a", "b", "a", "b", "a", "a", "a", "a", "a", "a", "b", "b", "b",
"c", "c", "c", "c", "a", "b", "a", "b", "a"
]
const result = arr.reduce(
(previousValue, currentValue) => {
if(currentValue in previousValue){
previousValue[currentValue] ++;
}else{
previousValue[currentValue] = 1;
}
return previousValue;
},
{}
)
console.log(result)
const arr = [
{ 年级: "2017级", 学院: "计算机学院", 专业: "物联网" },
{ 年级: "2017级", 学院: "计算机学院", 专业: "计算机科学" },
{ 年级: "2018级", 学院: "计算机学院", 专业: "软件工程" },
{ 年级: "2019级", 学院: "计算机学院", 专业: "软件工程" },
{ 年级: "2019级", 学院: "计算机学院", 专业: "物联网" },
{ 年级: "2020级", 学院: "计算机学院", 专业: "物联网" },
{ 年级: "2020级", 学院: "计算机学院", 专业: "计算机科学" },
{ 年级: "2020级", 学院: "计算机学院", 专业: "软件工程" },
{ 年级: "2017级", 学院: "电气学院", 专业: "自动化" },
{ 年级: "2018级", 学院: "电气学院", 专业: "自动化" },
{ 年级: "2019级", 学院: "电气学院", 专业: "自动化" },
{ 年级: "2020级", 学院: "电气学院", 专业: "自动化" },
]
// 根据指定字段的指定值获取分组
function getByTarget(arr, target, targetValue) {
// 如果没有指定具体年级,例如: 按照年级分组
if (!targetValue) {
const result = arr.reduce(
(previousValue, currentValue) => {
// 拿到当前要分组的条件
// 例如,currentValue是{ 年级: "2017级", 学院: "计算机学院", 专业: "物联网" }这样一个对象
// 那么,currentValue[target] 就是年级或者学院或者专业
let currentTargetValue = currentValue[target]
// 如果previousValue对象中没有值,则创建一个新数组
if (!previousValue[currentTargetValue]) {
previousValue[currentTargetValue] = []
}
// 将符合条件的添加到previousValue[currentTargetValue]数组中
previousValue[currentTargetValue].push(currentValue)
return previousValue;
},
{}
)
return result;
}
// 如果还指定了具体年级
let initObj = {}
initObj[targetValue] = [];
const result = arr.reduce(
(previousValue, currentValue) => {
// 不是目标值直接跳过
if (currentValue[target] !== targetValue) {
return previousValue;
}
// 符合要求则加入
previousValue[targetValue].push(currentValue);
return previousValue;
},
initObj
)
return result;
}
result05_01 = getByTarget(arr, "专业")
result05_02 = getByTarget(arr, "学院")
result05_03 = getByTarget(arr, "年级")
// 这里是为了确保函数返回值是一个map而不是数组(统一返回格式) 重在思路
result05_04 = getByTarget(arr, "年级", "2017级")["2017级"]
result05_05 = getByTarget(arr, "学院", "计算机学院")["计算机学院"]
result05_06 = getByTarget(arr, "专业", "自动化")["自动化"]
console.log("按专业分类");
console.log(result05_01)
console.log("按学院分类");
console.log(result05_02)
console.log("按年级分类");
console.log(result05_03)
console.log("取2017级");
console.log(result05_04)
console.log("取计算机学院");
console.log(result05_05)
console.log("取自动化专业");
console.log(result05_06)
结果:
按专业分类
{
‘物联网’: [
{ ‘年级’: ‘2017级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘物联网’ },
{ ‘年级’: ‘2019级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘物联网’ },
{ ‘年级’: ‘2020级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘物联网’ }
],
‘计算机科学’: [
{ ‘年级’: ‘2017级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘计算机科学’ },
{ ‘年级’: ‘2020级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘计算机科学’ }
],
‘软件工程’: [
{ ‘年级’: ‘2018级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘软件工程’ },
{ ‘年级’: ‘2019级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘软件工程’ },
{ ‘年级’: ‘2020级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘软件工程’ }
],
‘自动化’: [
{ ‘年级’: ‘2017级’, ‘学院’: ‘电气学院’, ‘专业’: ‘自动化’ },
{ ‘年级’: ‘2018级’, ‘学院’: ‘电气学院’, ‘专业’: ‘自动化’ },
{ ‘年级’: ‘2019级’, ‘学院’: ‘电气学院’, ‘专业’: ‘自动化’ },
{ ‘年级’: ‘2020级’, ‘学院’: ‘电气学院’, ‘专业’: ‘自动化’ }
]
}
按学院分类
{
‘计算机学院’: [
{ ‘年级’: ‘2017级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘物联网’ },
{ ‘年级’: ‘2017级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘计算机科学’ },
{ ‘年级’: ‘2018级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘软件工程’ },
{ ‘年级’: ‘2019级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘软件工程’ },
{ ‘年级’: ‘2019级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘物联网’ },
{ ‘年级’: ‘2020级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘物联网’ },
{ ‘年级’: ‘2020级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘计算机科学’ },
{ ‘年级’: ‘2020级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘软件工程’ }
],
‘电气学院’: [
{ ‘年级’: ‘2017级’, ‘学院’: ‘电气学院’, ‘专业’: ‘自动化’ },
{ ‘年级’: ‘2018级’, ‘学院’: ‘电气学院’, ‘专业’: ‘自动化’ },
{ ‘年级’: ‘2019级’, ‘学院’: ‘电气学院’, ‘专业’: ‘自动化’ },
{ ‘年级’: ‘2020级’, ‘学院’: ‘电气学院’, ‘专业’: ‘自动化’ }
]
}
按年级分类
{
‘2017级’: [
{ ‘年级’: ‘2017级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘物联网’ },
{ ‘年级’: ‘2017级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘计算机科学’ },
{ ‘年级’: ‘2017级’, ‘学院’: ‘电气学院’, ‘专业’: ‘自动化’ }
],
‘2018级’: [
{ ‘年级’: ‘2018级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘软件工程’ },
{ ‘年级’: ‘2018级’, ‘学院’: ‘电气学院’, ‘专业’: ‘自动化’ }
],
‘2019级’: [
{ ‘年级’: ‘2019级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘软件工程’ },
{ ‘年级’: ‘2019级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘物联网’ },
{ ‘年级’: ‘2019级’, ‘学院’: ‘电气学院’, ‘专业’: ‘自动化’ }
],
‘2020级’: [
{ ‘年级’: ‘2020级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘物联网’ },
{ ‘年级’: ‘2020级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘计算机科学’ },
{ ‘年级’: ‘2020级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘软件工程’ },
{ ‘年级’: ‘2020级’, ‘学院’: ‘电气学院’, ‘专业’: ‘自动化’ }
]
}
取2017级
[
{ ‘年级’: ‘2017级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘物联网’ },
{ ‘年级’: ‘2017级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘计算机科学’ },
{ ‘年级’: ‘2017级’, ‘学院’: ‘电气学院’, ‘专业’: ‘自动化’ }
]
取计算机学院
[
{ ‘年级’: ‘2017级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘物联网’ },
{ ‘年级’: ‘2017级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘计算机科学’ },
{ ‘年级’: ‘2018级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘软件工程’ },
{ ‘年级’: ‘2019级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘软件工程’ },
{ ‘年级’: ‘2019级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘物联网’ },
{ ‘年级’: ‘2020级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘物联网’ },
{ ‘年级’: ‘2020级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘计算机科学’ },
{ ‘年级’: ‘2020级’, ‘学院’: ‘计算机学院’, ‘专业’: ‘软件工程’ }
]
取自动化专业
[
{ ‘年级’: ‘2017级’, ‘学院’: ‘电气学院’, ‘专业’: ‘自动化’ },
{ ‘年级’: ‘2018级’, ‘学院’: ‘电气学院’, ‘专业’: ‘自动化’ },
{ ‘年级’: ‘2019级’, ‘学院’: ‘电气学院’, ‘专业’: ‘自动化’ },
{ ‘年级’: ‘2020级’, ‘学院’: ‘电气学院’, ‘专业’: ‘自动化’ }
]
或者更简单点如下:
const arr = [
{ 年级: "2017级", 学院: "计算机学院", 专业: "物联网" },
{ 年级: "2017级", 学院: "计算机学院", 专业: "计算机科学" },
{ 年级: "2018级", 学院: "计算机学院", 专业: "软件工程" },
{ 年级: "2019级", 学院: "计算机学院", 专业: "软件工程" },
{ 年级: "2019级", 学院: "计算机学院", 专业: "物联网" },
{ 年级: "2020级", 学院: "计算机学院", 专业: "物联网" },
{ 年级: "2020级", 学院: "计算机学院", 专业: "计算机科学" },
{ 年级: "2020级", 学院: "计算机学院", 专业: "软件工程" },
{ 年级: "2017级", 学院: "电气学院", 专业: "自动化" },
{ 年级: "2018级", 学院: "电气学院", 专业: "自动化" },
{ 年级: "2019级", 学院: "电气学院", 专业: "自动化" },
{ 年级: "2020级", 学院: "电气学院", 专业: "自动化" },
]
// 根据指定字段的指定值获取分组
function getByTarget(arr, target) {
// 如果没有指定具体年级,例如: 按照年级分组
const result = arr.reduce(
(previousValue, currentValue) => {
// 拿到当前要分组的条件
// 例如,currentValue是{ 年级: "2017级", 学院: "计算机学院", 专业: "物联网" }这样一个对象
// 那么,currentValue[target] 就是年级或者学院或者专业
let currentTargetValue = currentValue[target]
// 如果previousValue对象中没有值,则创建一个新数组
if (!previousValue[currentTargetValue]) {
previousValue[currentTargetValue] = []
}
// 将符合条件的添加到previousValue[currentTargetValue]数组中
previousValue[currentTargetValue].push(currentValue)
return previousValue;
},
{}
)
return result;
}
// 先进行总体分组
result05_01 = getByTarget(arr, "专业")
result05_02 = getByTarget(arr, "学院")
result05_03 = getByTarget(arr, "年级")
// 再进行具体分组,例如取出物联网专业
console.log(result05_01["物联网"]);
let arr = ["a","b","c","d","a","b","e","c","d"]
let result = arr.reduce((previousValue,currentValue) => {
if(previousValue.indexOf(currentValue) === -1){
previousValue.push(currentValue)
}
return previousValue
},[])
console.log(result);
Array.prototype.myMap = function(func, callbackThis){
// 最终返回新的数组
let res = [];
// 定义回调函数的执行环境
// call 第2个参数传入null 则this指向全部对象
let cbThis = callbackThis || null;
this.reduce(
(prev, next, index, arr)=>{
// 传入map回调函数拥有的参数
// 把每一项的执行结果push进入res
res.push(func.call(cbThis, next, index, arr));
},
null);
return res;
}
let arr = [1,2,3,4,5,6,7,8]
let result = arr11.myMap(Math.sqrt)
console.log(result)
/**
* @description: 自定义数组的reduce方法
* @params callback 回调函数
* @params initialValue 初始值
* @return 返回处理结果
*/
Array.prototype.myReduce = function (callback, initialValue) {
if (this == null) {
throw new TypeError('this is null or undefined');
}
if (typeof callback !== 'function') {
throw new TypeError(`${callback} is not a function`);
}
console.log(this); // 传进来的数组对象
const array = Object(this);
const len = array.length >>> 0;
let accumulator = initialValue;
for (let i = 0; i < len; i++) {
if (i in array) {
accumulator = callback.call(undefined, accumulator, array[i], i, array);
}
}
return accumulator;
};
// 使用
let array = [1,2,3,4]
let result = array.myReduce((pre,cur) => {
pre.push(cur+1)
return pre
},[])
console.log(result); // [2,3,4,5]
或者循环实现
var reduce = function (nums, fn, init) {
if (nums.length === 0)
return init
nums.forEach((item, index) => {
init = fn(init, item)
})
return init
};
// 被处理的数组
let nums = [1, 2, 3, 4]
// 初始值
let init = 100
// 回调函数
function sum(accum, curr) { return accum + curr * curr; }
console.log(reduce(nums, sum, init));