骚骚的reduce

arr.reduce(callback[, initialValue])
reduce为数组中的每一个元素依次执行callback函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:
  • accumulator
  • currentValue
  • currentIndex
  • array


回调函数第一次执行时,accumulator?和currentValue的取值有两种情况:调用reduce时提供initialValue,accumulator取值为initialValue,currentValue取数组中的第一个值;没有提供?initialValue,accumulator取数组中的第一个值,currentValue取数组中的第二个值
?
计算某个字符出现的次数
[...'abcdaabdcfggtre'].reduce((a,b)=>{a<strong>?a<strong>++:a<strong>=1;return a},{})
[b][b]字母游戏[/b][/b]
const anagrams = str => {
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");
[b][b]累加器[/b][/b]
const sum = arr => arr.reduce((acc, val) => acc + val, 0);
sum([1, 2, 3]);
[b][b]计数器[/b][/b]
const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0);
countOccurrences([1, 2, 3, 2, 2, 5, 1], 1);
[b][b]函数柯里化[/b][/b]
const curry = (fn, arity = fn.length, ...args) => 
arity <= args.length ? fn(...args) : curry.bind(null, fn, arity, ...args);

curry(Math.pow)(2)(10);
curry(Math.min, 3)(10)(50)(2);
 

[b][b]通过判断函数的参数取得当前函数的length(当然也可以自己指定),如果所传的参数比当前参数少,则继续递归下面,同时储存上一次传递的参数。[/b][/b]





[b][b]数组扁平化[/b][/b]
const deepFlatten = arr =>arr.reduce((a, v) => a.concat(Array.isArray(v) ? deepFlatten(v) : v), );
deepFlatten([1, [2, [3, 4, [5, 6]]]]);

[b][b]生成菲波列契数组[/b][/b]
const fibonacci = n => Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), );
fibonacci(5);
[b][b]pipe函数生成器[/b][/b]
const pipe = (...funcs) => arg => funcs.reduce((acc, func) => func(acc), arg);
pipe(btoa, x => x.toUpperCase())("Test");
 

[b][b]通过对传递的参数进行函数加工,之后将加工之后的数据作为下一个函数的参数,这样层层传递下去。[/b][/b]





[b][b]compose函数生成器[/b][/b]
const dispatch = action => {
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"));
[b][b]?
数据加工函数
[/b][/b]
const reducers = {
totalInEuros: (state, item) => {
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);
[b][b]对象空值判断[/b][/b]
const get = (p, o) => p.reduce((xs, x) => (xs && xs[x] ? xs[x] : null), o);
[b][b]分组[/b][/b]
const groupBy = (arr, func) =>
arr.map(typeof func === 'function' ? func : val => val[func]).reduce((acc, val, i) => {
acc[val] = (acc[val] || ).concat(arr);
return acc;
}, {});
groupBy([6.1, 4.2, 6.3], Math.floor);
groupBy(['one', 'two', 'three'], 'length');
[b][b]对象过滤[/b][/b]
const pick = (obj, arr) =>
arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {});

pick({ a: 1, b: '2', c: 3 }, ['a', 'c']);
[b][b]promise顺序执行[/b][/b]
const runPromisesInSeries = ps => 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')])
[b][b]排序函数[/b][/b]
const orderBy = (arr, props, orders) =>
[...arr].sort((a, b) =>
props.reduce((acc, prop, i) => {
if (acc === 0) {
const [p1, p2] = orders && orders === '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, ['name', 'age']);
[b][b]快速选择器[/b][/b]
const select = (from, selector) =>
selector.split('.').reduce((prev, cur) => prev && prev[cur], from);

const obj = { selector: { to: { val: 'val to select' } } };
select(obj, 'selector.to.val');

0 个评论

要回复文章请先登录注册