js数组方法reduce经典用法代码分享

以下是个人在工作中收藏总结的一些关于javascript数组方法reduce的相关代码片段,后续遇到其他使用这个函数的场景,将会陆续添加,这里作为备忘。

javascript数组那么多方法,为什么我要单挑reduce方法一个原因是我对这个方法掌握不够,不能够用到随心所欲。另一个方面,我也感觉到了这个方法的庞大魅力,在许多的场景中发挥着神奇的作用。

理解reduce函数

reduce() 方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始缩减,最终为一个值。

rush:xhtml;"> arr.reduce([callback,initialValue])

看如下例子:

// 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 (prevIoUs,current) => {
reducers.reduce((p,r) => r(p,current),prevIoUs);
}
}
// 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']);

bed-version="2" data-user="rynxiao" data-default-tab="js" data-slug-hash="QaqONY" data-theme-id="0" data-height="265">根据给出的键值来遍历,比较对象中是否存在相同键值的的值,然后通过逗号表达式把赋值后的对象赋给下一个的初始值

bed-version="2" data-user="rynxiao" data-default-tab="js" data-slug-hash="QaqONY" data-theme-id="0" data-height="265">

片段十四:数组中删除指定位置的值

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);

bed-version="2" data-user="rynxiao" data-default-tab="js" data-slug-hash="QaqONY" data-theme-id="0" data-height="265">

bed-version="2" data-user="rynxiao" data-default-tab="js" data-slug-hash="QaqONY" data-theme-id="0" data-height="265">首先根据filter函数过滤出数组中符合条件的值,然后使用reduce在原数组中删除符合条件的值,可以得出最后arr的值变成了[1,3]

bed-version="2" data-user="rynxiao" data-default-tab="js" data-slug-hash="aELVpZ" data-theme-id="0" data-height="265">

片段十五: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')]);

bed-version="2" data-user="rynxiao" data-default-tab="js" data-slug-hash="aELVpZ" data-theme-id="0" data-height="265">

片段十六:排序

[...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']);

bed-version="2" data-user="rynxiao" data-default-tab="js" data-slug-hash="Qaqomr" data-theme-id="0" data-height="265">

片段十七:选择

selector.split('.').reduce((prev,cur) => prev && prev[cur],from); const obj = { selector: { to: { val: 'val to select' } } }; select(obj,'selector.to.val');

bed-version="2" data-user="rynxiao" data-default-tab="js" data-slug-hash="MrEOzK" data-theme-id="0" data-height="265">以上就是我们为大家整理的关于js数组方法reduce经典用法代码内容,感谢你对编程之家的支持

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...