Home  >  Article  >  Web Front-end  >  Classic usage of js array method reduce

Classic usage of js array method reduce

小云云
小云云Original
2018-01-09 09:04:222077browse

There are so many methods for

javascript arrays. Why should I single out the reduce method? One reason is that I don’t know enough about this method to use it as I like. On the other hand, I also feel the huge charm of this method, which plays a magical role in many scenes. This article mainly compiles a lot of classic code snippets about the js array method reduce for you, so that you can better understand the use of reduce examples. Let's study together. Hope it helps everyone.

The following are some relevant code snippets about the javascript array methodreduce that I collected and summarized at work. When encountering other scenarios where this function is used, they will be added one after another. Here is a backup forget.

UnderstandingreduceFunction

reduce() method receives a function as an accumulator (accumulator), and each value in the array starts to decrease (from left to right). Finally a value.


arr.reduce([callback, initialValue])

Look at the following example:


let arr = [1, 2, 3, 4, 5];

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

Fragment 1: Alphabet Game


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"); // 结果会是什么呢?

reduce is responsible for filtering out the first letter of each execution, and recursion is responsible for arranging and combining the remaining letters.

Fragment Two: Accumulator


const sum = arr => arr.reduce((acc, val) => acc + val, 0);
sum([1, 2, 3]);

Fragment Three: Counter


const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0);
countOccurrences([1, 2, 3, 2, 2, 5, 1], 1);

Loop through the array. Whenever a value is encountered that is equal to the given value, 1 will be added, and the following will be added. The result is used as the initial value for the next time.

Fragment 4: Function Currying

The purpose of function currying is to store data and then execute it in the last step.


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

Get the length of the current function by judging the parameters of the function (of course you can also specify it yourself). If the passed parameters are less than the current parameters, Then continue the recursion and store the parameters passed last time.

Fragment Five: Array Flattening


const deepFlatten = arr => 
 arr.reduce((a, v) => a.concat(Array.isArray(v) ? deepFlatten(v) : v), []);
deepFlatten([1, [2, [3, 4, [5, 6]]]]);

Fragment Six: Generate Fiborechi Array


const fibonacci = n => Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), []);
fibonacci(5);

Fragment Seven: Pipe Processor


const pipe = (...funcs) => arg => funcs.reduce((acc, func) => func(acc), arg);
pipe(btoa, x => x.toUpperCase())("Test");

By performing function processing on the passed parameters, and then using the processed data as the parameters of the next function, it is passed on layer by layer.

Fragment 8: Middleware


const dispatch = action => {
 console.log(&#39;action&#39;, 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"));

redux# This method is used in the classic compose function in ##. Through multiple layers of middleware, function execution is triggered when the action is actually initiated.

Fragment 9: redux-actions processing of state


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

Fragment ten: Data processor


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

Fragment eleven: Object null value judgment


let school = {
 name: &#39;Hope middle school&#39;,
 created: &#39;2001&#39;,
 classes: [
  {
   name: &#39;三年二班&#39;,
   teachers: [
    { name: &#39;张二蛋&#39;, age: 26, sex: &#39;男&#39;, actor: &#39;班主任&#39; },
    { name: &#39;王小妞&#39;, age: 23, sex: &#39;女&#39;, actor: &#39;英语老师&#39; }
   ]
  },
  {
   name: &#39;明星班&#39;,
   teachers: [
    { name: &#39;欧阳娜娜&#39;, age: 29, sex: &#39;女&#39;, actor: &#39;班主任&#39; },
    { name: &#39;李易峰&#39;, age: 28, sex: &#39;男&#39;, actor: &#39;体育老师&#39; },
    { name: &#39;杨幂&#39;, age: 111, sex: &#39;女&#39;, actor: &#39;艺术老师&#39; }
   ]
  }
 ]
};
// 常规做法
school.classes &&
school.classes[0] &&
school.classes[0].teachers &&
school.classes[0].teachers[0] &&
school.classes[0].teachers[0].name
// reduce方法
const get = (p, o) => p.reduce((xs, x) => (xs && xs[x] ? xs[x] : null), o);
get([&#39;classes&#39;, 0, &#39;teachers&#39;, 0, &#39;name&#39;], school); // 张二蛋

Fragment twelve: Grouping


const groupBy = (arr, func) =>
arr.map(typeof func === &#39;function&#39; ? func : val => val[func]).reduce((acc, val, i) => {
 acc[val] = (acc[val] || []).concat(arr[i]);
 return acc;
}, {});
groupBy([6.1, 4.2, 6.3], Math.floor); 
groupBy([&#39;one&#39;, &#39;two&#39;, &#39;three&#39;], &#39;length&#39;);

First pass

mapCalculate all key values, and then classify them according to the created values

Fragment 13: Object filtering


const pick = (obj, arr) =>
arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {});

Traverse according to the given key value, compare whether there is a value with the same key value in the object, and then assign the assigned object to the next initial value through a comma expression

Fragment 14: Delete the value at the specified position in the array


const remove = (arr, func) =>
 Array.isArray(arr)
 ? arr.filter(func).reduce((acc, val) => {
   arr.splice(arr.indexOf(val), 1);
   return acc.concat(val);
 }, []) : [];
const arr = [1, 2, 3, 4];
remove(arr, n => n % 2 == 0);

First filter out the qualified values ​​in the array according to the

filter function, and then use reduce to delete the qualified values ​​in the original array. It can be concluded that the final value of arr becomes [1 , 3]

Fragment 15: promises are executed in order


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(&#39;hello&#39;)]);

Fragment Sixteen: Sorting


const orderBy = (arr, props, orders) =>
 [...arr].sort((a, b) =>
  props.reduce((acc, prop, i) => {
   if (acc === 0) {
    const [p1, p2] = orders && orders[i] === &#39;desc&#39; ? [b[prop], a[prop]] : [a[prop], b[prop]];
    acc = p1 > p2 ? 1 : p1 < p2 ? -1 : 0;
   }
   return acc;
  }, 0)
 );
const users = [{ name: &#39;fred&#39;, age: 48 }, { name: &#39;barney&#39;, age: 36 }, { name: &#39;fly&#39;, age: 26 }];
orderBy(users, [&#39;name&#39;, &#39;age&#39;], [&#39;asc&#39;, &#39;desc&#39;]); 
orderBy(users, [&#39;name&#39;, &#39;age&#39;]);

Fragment Seventeen: Select


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

Related recommendations:

Using MapReduce in MongoDB

Review js from the objects in the array reduce()

Usage and tips of the array Reduce() function in JavaScript

The above is the detailed content of Classic usage of js array method reduce. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn