My Little World

数组的map和reduce

数组的map方法

1
2
3
4
5
6
7
let arr = [1,2,3,4,5];
let arr1 = arr.map(function(val,index,arr){
console.log(val,index,arr)
return val+1
})
console.log(arr1)//[2, 3, 4, 5, 6]
console.log(arr) //[1, 2, 3, 4, 5]

在map中可以传递一个函数,数组的每一项作为参数调用这个函数,然后返回根据该数组项得到的结果,每一个数组项返会一个结果,从而组成新的数组

函数的参数有三个,第一项为数组按序传进的一个值,该值的index和数组本身

整个结果产生新数组,原来数组不变

数组的reduce 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
例1.
let arr = [1,2,3];
let result = arr.reduce(function(preresult,item){
return preresult += item;
},0)
console.log(result) //6

例2.
let result4 = arr.reduce(function(preresult,item){
preresult.name += item;
return preresult
},{name:0})
console.log(result4); //{name:6}

reduce 用于对数组每一项进行累计计算,每一项计算结果作为参数参加数组下一项的计算,最终返回计算结果

例1中单纯对数组每一项进行叠加处理,返回叠加结果
例2同样进行叠加只是叠加结果放在对象中返回

reduce(callback(),initval)

需要两个参数,一个是用于累计计算的callback函数,一个是初始值,见上两例

callback()函数有四个参数依次为:

preVal (上一次调用回调返回的值,或者是提供的初始值(initialValue))

currentValue (数组中当前被处理的元素)

index (当前元素在数组中的索引)

array (调用 reduce 的数组)

初始值会在第一次调用时当作回调函数callback的第一个参数使用

希望返回值是什么类型的数据,初始值就要设置为什么样的类型,callback返回值也是该类型;或者说是在这里设置返回值的类型

整个处理过程就是拿初始值initval和数组第一个值在callback里面进行处理,返回结果result,result当作callback的preval参数和数组第二个元素传入callback在处理,直到数组全部元素被处理完,返回一个最终处理结果

高级应用
对对象数组元素进行累计计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var reducers = {  
totalInEuros : function(state, item) {
return state.euros += item.price * 0.897424392;
},
totalInYen : function(state, item) {
return state.yens += item.price * 113.852;
}
};

var manageReducers = function(reducers) {
return function(state, item) {
return Object.keys(reducers).reduce(
function(nextState, key) {
reducers[key](state, item);
return state;
},
{}
);
}
};

var bigTotalPriceReducer = manageReducers(reducers);
var initialState = {euros:0, yens: 0};
var items = [{price: 10}, {price: 120}, {price: 1000}];
var totals = items.reduce(bigTotalPriceReducer, initialState);
console.log(totals);
//{euros: 1014.08956296, yens: 128652.76}

该例的目的是将对象数组items的元素属性price进行不同处理操作然后将结果分别保存到结果对象的属性中

处理的关键是manageReducers返回的作为items callback的函数bigTotalPriceReducer,

处理思路是items每用一个元素调用callback时,callback的处理过程是将这个元素作为参数调用reducers 对象里面设置的每一个处理函数,

调用reducers处理函数的过程同样使用一个reduce方法进行处理

Object.keys(obj)方法返回对象键值组成的数组

当items的元素参加完reducers所有处理函数后,返回的结果参加下一个元素的计算最终返回结果

扩展:

1.在reduces中设置对items不同属性的计算,从而得到不同属性的结算结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var reducers = {  
totalInEuros : function(state, item) {
return state.euros += item.p1;
},
totalInYen : function(state, item) {
return state.yens += item.price * 113.852;
}
};

var bigTotalPriceReducer = manageReducers(reducers);
var initialState = {euros:0, yens: 0};
var items = [{price: 10,p1:1}, {price: 120,p1:1}, {price: 1000,p1:1}];
var totals = items.reduce(bigTotalPriceReducer, initialState);
console.log(totals);
//{euros: 3, yens: 128652.76}

2.计算对象数组属性值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var manageReducers = function(state, item) {
return Object.keys(item).reduce(
function(nextState, key) {
state[key] +=item[key];
return state;
},
{}
);
};

var initialState = {price:0, p1: 0};
var items = [{price: 10,p1:1}, {price: 120,p1:1}, {price: 1000,p1:1}];
var totals = items.reduce(manageReducers, initialState);
console.log(totals);
//{price: 1130, p1: 3}

参阅资料