js数组方法reduce经典用法代码分享
前端之家收集整理的这篇文章主要介绍了
js数组方法reduce经典用法代码分享,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
以下是个人在工作中收藏总结的一些关于javascript数组方法reduce
的相关代码片段,后续遇到其他使用这个函数的场景,将会陆续添加,这里作为备忘。
javascript数组那么多方法,为什么我要单挑reduce
方法,一个原因是我对这个方法掌握不够,不能够用到随心所欲。另一个方面,我也感觉到了这个方法的庞大魅力,在许多的场景中发挥着神奇的作用。
理解reduce
函数
reduce() 方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始缩减,最终为一个值。
看如下例子:
// 10代表初始值,p代表每一次的累加值,在第一次为10
// 如果不存在初始值,那么p第一次值为1
// 此时累加的结果为15
let sum = arr.reduce((p,c) => p + c,10); // 25
// 转成es5的写法即为:
var sum = arr.reduce(function(p,c) {
console.log(p);
return p + c;
},10);
片段一:字母游戏
{
if (str.length <= 2) {
return str.length === 2 ? [str,str[1] + str[0]] : str;
}
return str.split("").reduce((acc,letter,i) => {
return acc.concat(anagrams(str.slice(0,i) + str.slice(i + 1)).map(val => letter + val));
},[]);
}
anagrams("abc"); // 结果会是什么呢?
reduce
负责筛选出每一次执行的首字母,递归负责对剩下字母的排列组合。
片段二:累加器
arr.reduce((acc,val) => acc + val,0);
sum([1,3]);
片段三:计数器
arr.reduce((a,v) => v === value ? a + 1 : a + 0,0);
countOccurrences([1,5,1],1);
循环数组,每遇到一个值与给定值相等,即加1,同时将加上之后的结果作为下次的初始值。
函数柯里化的目的就是为了储存数据,然后在最后一步执行。
arity <= args.length ? fn(...args) : curry.bind(null,fn,arity,...args);
curry(Math.pow)(2)(10);
curry(Math.min,3)(10)(50)(2);
通过判断函数的参数取得当前函数的length
(当然也可以自己指定),如果所传的参数比当前参数少,则继续递归下面,同时储存上一次传递的参数。
片段五:数组扁平化
arr.reduce((a,v) => a.concat(Array.isArray(v) ? deepFlatten(v) : v),[]);
deepFlatten([1,[2,[3,[5,6]]]]);
片段六:生成菲波列契数组
Array(n).fill(0).reduce((acc,val,i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),[]);
fibonacci(5);
片段七:管道加工器
arg => funcs.reduce((acc,func) => func(acc),arg);
pipe(btoa,x => x.toUpperCase())("Test");
通过对传递的参数进行函数加工,之后将加工之后的数据作为下一个函数的参数,这样层层传递下去。
片段八:中间件
{
console.log('action',action);
return action;
}
const middleware1 = dispatch => {
return action => {
console.log("middleware1");
const result = dispatch(action);
console.log("after middleware1");
return result;
}
}
const middleware2 = dispatch => {
return action => {
console.log("middleware2");
const result = dispatch(action);
console.log("after middleware2");
return result;
}
}
const middleware3 = dispatch => {
return action => {
console.log("middleware3");
const result = dispatch(action);
console.log("after middleware3");
return result;
}
}
const compose = middlewares => middlewares.reduce((a,b) => args => a(b(args)))
const middlewares = [middleware1,middleware2,middleware3];
const afterDispatch = compose(middlewares)(dispatch);
const testAction = arg => {
return { type: "TEST_ACTION",params: arg };
};
afterDispatch(testAction("1111"));
<div class="sourceCode">redux
中经典的compose
函数中运用了这种方式,通过对中间件的重重层叠,在真正发起action的时候触发函数执行。
<div class="sourceCode">
片段九:redux-actions对state的加工片段
<div class="jb51code">
<pre class="brush:xhtml;">
// redux-actions/src/handleAction.js
const handleAction = (type,reducer,defaultState) => {
const types = type.toString();
const [nextReducer,throwReducer] = [reducer,reducer];
return (state = defaultState,action) => {
const { type: actionType } = action;
if (!actionType || types.indexOf(actionType.toString()) === -1) {
return state;
}
return (action.error === true ? throwReducer : nextReducer)(state,action);
}
}
// reduce-reducers/src/index.js
const reduceReducer = (...reducers) => {
return (prev
IoUs,current) => {
reducers.reduce((p,r) => r(p,current),prev
IoUs);
}
}
// redux-actions/src/handleActions.js
const handleActions = (handlers,defaultState,{ namespace } = {}) => {
// reducers的扁平化
const flattenedReducerMap = flattenReducerMap(handles,namespace);
// 每一种ACTION下对应的reducer处理方式
const reducers = Reflect.ownkeys(flattenedReducerMap).map(type => handleAction(
type,flattenedReducerMap[type],defaultState
));
// 状态的加工器,用于对reducer的执行
const reducer = reduceReducers(...reducers);
// reducer触发
return (state = defaultState,action) => reducer(state,action);
}
片段十:数据加工器
{
return state.euros += item.price * 0.897424392;
},totalInYen: (state,item) => {
return state.yens += item.price * 113.852;
}
};
const manageReducers = reducers => {
return (state,item) => {
return Object.keys(reducers).reduce((nextState,key) => {
reducers[key](state,item);
return state;
},{})
}
}
const bigTotalPriceReducer = manageReducers(reducers);
const initialState = { euros: 0,yens: 0 };
const items = [{ price: 10 },{ price: 120 },{ price: 1000 }];
const totals = items.reduce(bigTotalPriceReducer,initialState);
片段十一:对象空值判断
p.reduce((xs,x) => (xs && xs[x] ? xs[x] : null),o);
get(['classes','teachers','name'],school); // 张二蛋
片段十二:分组
arr.map(typeof func === 'function' ? func : val => val[func]).reduce((acc,i) => {
acc[val] = (acc[val] || []).concat(arr[i]);
return acc;
},{});
groupBy([6.1,4.2,6.3],Math.floor);
groupBy(['one','two','three'],'length');
map计算出所有的键值,然后再根据建值进行归类
片段十三:对象过滤
arr.reduce((acc,curr) => (curr in obj && (acc[curr] = obj[curr]),acc),{});
pick({ a: 1,b: '2',c: 3 },['a','c']);
片段十四:数组中删除指定位置的值
Array.isArray(arr)
? arr.filter(func).reduce((acc,val) => {
arr.splice(arr.indexOf(val),1);
return acc.concat(val);
},[]) : [];
const arr = [1,4];
remove(arr,n => n % 2 == 0);
filter函数过滤出数组中符合条件的值,然后使用reduce
在原数组中删除符合条件的值,可以得出最后arr的值变成了[1,3]
片段十五:promise按照顺序执行
ps.reduce((p,next) => p.then(next),Promise.resolve());
const delay = d => new Promise(r => setTimeout(r,d));
const print = args => new Promise(r => r(args));
runPromisesInSeries([() => delay(1000),() => delay(2000),() => print('hello')]);
片段十六:排序
[...arr].sort((a,b) =>
props.reduce((acc,prop,i) => {
if (acc === 0) {
const [p1,p2] = orders && orders[i] === 'desc' ? [b[prop],a[prop]] : [a[prop],b[prop]];
acc = p1 > p2 ? 1 : p1 < p2 ? -1 : 0;
}
return acc;
},0)
);
const users = [{ name: 'fred',age: 48 },{ name: 'barney',age: 36 },{ name: 'fly',age: 26 }];
orderBy(users,['name','age'],['asc','desc']);
orderBy(users,'age']);
片段十七:选择
selector.split('.').reduce((prev,cur) => prev && prev[cur],from);
const obj = { selector: { to: { val: 'val to select' } } };
select(obj,'selector.to.val');
方法reduce经典用法代码内容,感谢你对编程之家的支持。