Array.prototype.reduce is a very magical method in JS. It should be applied in too many scenarios, such as realizing asynchronous function serial, aggregating data and so on. In this paper, reduce is used to realize the tool functions we use in daily use. I hope that each example can be realized manually, so that I can get used to using Reduce to solve problems and update my own technology with JS standards.

Pipe line

The PIPE pipe is probably one of the most common operators we use in Linux, passing the results of the previous function to the next, and so on

Example: When splitting functions into smaller sizes, we can pipe calculations together to improve readability, nesting like this is too tiring to look at and uncomfortable to write.


const calc1 = x => x * 2
const calc2 = x => x - 1
const calc3 = x => x * 3

const sum = calc3(calc2(calc1(10)))
Copy the code

Use pipe after

const calc = pipe(calc1, calc2, calc3)
const sum = calc(10)
Copy the code

Implement pipe with reduce:

const pipe = (. functions) = > (initialValue) =>
  functions.reduce((value, fn) = > fn(value), initialValue);
Copy the code

Reduce is an iterator that takes two arguments, the second of which, optionally, is the value to start the iteration, The first parameter is a callback function. The first value in the function is the result of the last calculation, and the second value is the value of the current iteration.

Compose combination

Compose and Pipe are very similar. Pipe executes from left to right, and compose executes from right to left, so the method reduceRight is used in the implementation

const compose = (. functions) = > (initialValue) =>
  functions.reduceRight((value, fn) = > fn(value), initialValue);
Copy the code

Compact removes false values

We usually use filter to remove false values

const falseyArray = [0.null.1.undefined.2.' '.3.false.4.NaN]

const compact = (arr) = > arr.filter(el= > el)
compact(falseyArray) // [1, 2, 3, 4]
Copy the code

It is also possible to use Reduce

const compact = list= > 
    list.reduce((acc, value) = > {
        value && acc.push(value)
        return acc
    }, [])
Copy the code

Implementation includes

The includes function is also useful in simplifying conditional judgments

const value = 'cat'
if (value === 'cat' || value === 'dog' || value === 'pig') {// statement
}

// Can be written as
if(['cat'.'dog'.'pig'].includes(value)){
    // statement
}
Copy the code

Implement using Reduce

const includes = (item, list) = >
  list.reduce((isIncluded, value) = > isIncluded || item === value, false);
Copy the code

Flatten Flatten an array

Array.prototype.flatten: array.prototype.flatten: array.prototype.flatten: array.prototype.flatten

flatten([[1.2], [3.4]]);  // [1, 2, 3, 4]
Copy the code

Implementation:

function flatten(arr){
    return arr.reduce((pre, next) = > {
        return pre.concat(Array.isArray(next) ? flatten(next) : next) 
    }, [])
}
Copy the code

In addition to the Reduce implementation there are several other implementations:

  1. Use toString
[[[1.2], [1.2.3]], [1.2]].toString().split(', ').map(Number)
Copy the code
  1. Using deconstruction extraction
const flatten = list= > {
    while(list.some((item) = > Array.isArray(item))){ list = [].concat(... list) }return list;
}
Copy the code

repeat

Repeat is a method that String has, but when processing data, we often use complicated data types such as object. In this case, repeat cannot be used. We can use reduce to achieve one

const repeat = (item, times) = >
  Array.from({ length: times }).reduce((acc) = > {
    acc.push(item);

    returnacc; } []);/ / use

repeat({ favoriteLanguage: 'JavaScript' }, 2);

/* [{ favoriteLanguage: 'JavaScript' }, { favoriteLanguage: 'JavaScript' }], */
Copy the code

Times executes multiple times

Sometimes you want a calculation to execute multiple times and return a list, similar to the repeat above

times((x) = > x * 2.3);
/ / [0, 2, 4]
Copy the code

Implementation:

const times = (fn, numTimes) = > Array.from({length: numTimes}).reduce((acc, _, index) = > {
    acc.push(fn(index))
    return acc
}, [])
Copy the code

Deduplicate Array duplicates

You can write this the next time an interview question doesn’t allow you to use the Set feature

const deduplicate = (items) = > {
  const cache = {};

  return items.reduce((acc, item) = > {
    const alreadyIncluded = cache[item] === true;

    if(! alreadyIncluded) { cache[item] =true;
      acc.push(item);
    }

    returnacc; } []); }; deduplicate([[1], [1] and {hello: 'world' }, { hello: 'world' }]);
// [[1], { hello: 'world' }]
Copy the code

Reverse reverse

Reverse has a problem with changing the original array, so we’ll implement a reverse ourselves to avoid this side effect

Implementation:

const reverse = list= > list.reduceRight((acc, value) = > {
    acc.push(value)
    return acc;
}, [])

reverse([1.2.3]);
/ / [3, 2, 1)
Copy the code

adjust

Apply a function to the value at the specified position in the array, such as [1, -2, 3]. Want to apply a function math.abs () to the second element of the array to correct the data. If the given array index is out of bounds, the original array is returned.

const adjust = (fn, list, index) = > {
    if(index > list.length) return list;
    
    list.reduce((acc, value, i) = > {
        index === i ? acc.push(fn(value)) : acc.push(value)
        returnacc; }}, [])Copy the code

fromPairs

[[‘age’, 20], [‘name’, ‘evle’]] to {name: ‘evle’, age: 10}

const fromPairs  = list= > list.reduce((acc, pairs) = > {
	const [k, v] = pairs;
	acc[k] = v
	return acc;
}, {})
Copy the code

range

Range (15, 20) // => 15, 16, 17, 18, 19, 20

const range = (start, end) = > Array.from({length: end - start + 1}).reduce((acc, _, index) = > {
    acc.push(start + index)
    return acc;
}, [])
Copy the code

insertAll

Inserts an array at the specified position in an array, at the end if the given position is out of bounds

insertAll(1[2.3.4], [1.5]);
// [1, 2, 3, 4, 5]

insertAll(10[2.3.4], [1.5]);
// [1, 5, 2, 3, 4]
Copy the code

Implementation:

const insertAll = (index, subList, list) = > {
    if(list.length < index) {
        return list.concat(subList)
    }
    
    return list.reduce((acc, value, i) = >{ index === i ? acc.push(... subList, value) : acc.push(value)returnacc; }}, [])Copy the code

mergeAll

Combine the objects in the list into one object

mergeAll([
    { js: 'reduce' },
    { elm: 'fold' },
    { java: 'collect' },
    { js: 'reduce'}]);/* { js: 'reduce', elm: 'fold', java: 'collect' } */
Copy the code

Implementation:

const mergeAll = (list) = > list.reduce((acc, value) = > {
    const [pair] = Object.entries(value)
    const [k, v] = pair;
    acc[k] = v;
    return acc
}, {})
Copy the code

xprod

Xprod combines elements from a given array into various results, such as

xprod(['Hello'.'World'], ['JavaScript'.'Reduce']);
/* [ ['Hello', 'JavaScript'], ['Hello', 'Reduce'], ['World', 'JavaScript'], ['World', 'Reduce'] ] */
Copy the code

Implementation:

const xprod = (list1, list2) = > list1.reduce((acc, value) = > {
    
    list2.forEach(el= >{
        acc.push([value, el])
    })
    
    return acc
}, []) 
Copy the code

intersperse

Inserts a specified element in the middle of each element of the array

intersperse('Batman'[1.2.3.4.5.6]);
// [1, 'Batman', 2, 'Batman', 3, 'Batman', 4, 'Batman', 5, 'Batman', 6]

intersperse('Batman'[]);/ / []
Copy the code

Implementation:

const intersperse = (spreator, list) = > list.reduce((acc, value, index) = > {
    index === list.length - 1 ? acc.push(value) : acc.push(value, spreator)
    return acc;
}, [])
Copy the code

insert

Insert an element at the specified position in the array. Previously we used splice() to insert an element in the array. Now we use reduce

insert(2['Batman'], [1.2.3]);
// [1, 2, ['Batman'], 3]

insert(10['Batman'], [1.2.3]);
// [1, 2, 3, ['Batman']]
Copy the code

Implementation:

const insert = (index, newItem, list) = > {
  if (index > list.length - 1) {
    return [...list, newItem];
  }

  return list.reduce((acc, value, sourceArrayIndex) = > {
    index === sourceArrayIndex ? acc.push(newItem, value) : acc.push(value);
    returnacc; } []); };Copy the code

arrayIntoObject

Sometimes there is no key in the data obtained from the server, and the data has no regularity. In order to facilitate operation, we generally aggregate the data

const users = [
    { username: 'JX01'.status: 'offline' },
    { username: 'yazeedBee'.status: 'online'}];// Actually what we want is
{
  JX01: {
    username: 'JX01'.status: 'offline'
  },
  yazeedBee: { username: 'yazeedBee'.status: 'online'}}/ / or
{
  offline: {
    username: 'JX01'.status: 'offline'
  },
  online: { username: 'yazeedBee'.status: 'online'}}Copy the code

Implementation:

const arrayIntoObject = (key, list) = >
  list.reduce((acc, obj) = > {
    const value = obj[key];

    acc[value] = obj;

    return acc;
  }, {});
Copy the code