【译】再来10个使用reduce制作的JavaScript实用函数

902 阅读4分钟

原文链接:yazeedb.com/posts/10-mo…
原作者:Yazeed Bzadough
翻译者:发呆小贤

这次,带上单元测试

之前,我写了约10个使用reduce实现的工具函数。它广受好评,当我完成的时候,我对这个伟大的多功能工具有了更深的欣赏。为什么不再来10个呢?

这些函数其中很多是由优秀的库 LodashRamda 所启发。我还编写了单元测试以确保行为正确。您可以在 Github仓库 上看到所有内容。

1. pipe

参数

  1. ...functions - 任意数量的函数

描述

从左到右执行函数组合。管道的第一个参数用作初始值,并在通过每个函数时进行转换。

实现

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

用例

const mathSequence = pipe(
  (x) => x * 2,
  (x) => x - 1,
  (x) => x * 3
);

mathSequence(1); // 3
mathSequence(2); // 9
mathSequence(3); // 15

有关更多详细的信息,我在 这里 写了一篇关于 pipe 的文章。

2. compose

参数

  1. ...functions - 任意数量的函数

描述

从右到左执行函数组合。管道的第一个参数用作初始值,并在通过每个函数时进行转换。

工作原理和 pipe 相似,但方向相反。

实现

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

用例

const mathSequence = compose(
  (x) => x * 2,
  (x) => x - 1,
  (x) => x * 3
);

mathSequence(1); // 4
mathSequence(2); // 10
mathSequence(3); // 16

有关更多详细的信息,我在 这里 写了一篇关于 compose 的文章。

3. zip

参数

  1. list1 - 列表1
  2. list2 - 列表2

描述

通过索引对两个列表中的元素进行配对。如果两个列表长度不相等,则使用较短列表的长度。

实现

const zip = (list1, list2) => {
  const sourceList = list1.length > list2.length ? list2 : list1;

  return sourceList.reduce((acc, _, index) => {
    const value1 = list1[index];
    const value2 = list2[index];

    acc.push([value1, value2]);

    return acc;
  }, []);
};

用例

zip([1, 3], [2, 4]); // [[1, 2], [3, 4]]

zip([1, 3, 5], [2, 4]); // [[1, 2], [3, 4]]

zip([1, 3], [2, 4, 5]); // [[1, 2], [3, 4]]

zip(['Decode', 'secret'], ['this', 'message!']);
// [['Decode', 'this'], ['secret', 'message!']]

4. intersperse

参数

  1. separator - 要插入的元素
  2. list - 列表

描述

在列表的每个元素之间插入分隔符。

实现

const intersperse = (separator, list) =>
  list.reduce((acc, value, index) => {
    if (index === list.length - 1) {
      acc.push(value);
    } else {
      acc.push(value, separator);
    }

    return acc;
  }, []);

用例

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

intersperse('Batman', []);
// []

5. insert

参数

  1. index - 插入元素的索引
  2. newItem - 要插入的新元素
  3. list - 列表

描述

在给定的索引处插入一个元素。如果索引太大,则将元素插入列表的末尾。

实现

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

  return list.reduce((acc, value, sourceArrayIndex) => {
    if (index === sourceArrayIndex) {
      acc.push(newItem, value);
    } else {
      acc.push(value);
    }

    return acc;
  }, []);
};

用例

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

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

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

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

6. flatten

参数

  1. list - 列表

描述

将列表按一级展平。

实现

const flatten = (list) => list.reduce((acc, value) => acc.concat(value), []);

用例

flatten([[1, 2], [3, 4]]);
// [1, 2, 3, 4]

flatten([[1, 2], [[3, 4]]]);
// [1, 2, [3, 4]]

flatten([[[1, 2]], [3, 4]]);
// [[1, 2], 3, 4]

flatten([[[1, 2], [3, 4]]]);
// [[1, 2], [3, 4]]

7. flatMap

参数

  1. mappingFunction - 每一项要运行的函数
  2. list - 列表

描述

根据给定的函数映射每个列表项,然后展平结果。

实现

// Kind of cheating, because we already implemented flatten 😉
// 有点作弊,因为我们已经实现了flatten
const flatMap = (mappingFunction, list) => flatten(list.map(mappingFunction));

用例

flatMap((n) => [n * 2], [1, 2, 3, 4]);
// [2, 4, 6, 8]

flatMap((n) => [n, n], [1, 2, 3, 4]);
// [1, 1, 2, 2, 3, 3, 4, 4]

flatMap((s) => s.split(' '), ['flatMap', 'should be', 'mapFlat']);
// ['flatMap', 'should', 'be', 'mapFlat']

8. includes

参数

  1. item - 要检查的元素
  2. list - 列表

描述

检查列表是否包含给定的列表元素。如果找到元素,则返回 true。否则返回 false

实现

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

用例

includes(3, [1, 2, 3]); // true
includes(3, [1, 2]); // false
includes(0, []); // false

9. compact

参数

  1. list - 列表

描述

从列表中删除“假”值。

实现

const compact = (list) =>
  list.reduce((acc, value) => {
    if (value) {
      acc.push(value);
    }

    return acc;
  }, []);

用例

compact([0, null, 1, undefined, 2, '', 3, false, 4, NaN]);
// [1, 2, 3, 4]

10. arrayIntoObject

参数

  1. key - 用作新对象键的字符串
  2. list - 列表

描述

使用给定键作为新对象的键,将数组转换为对象。

实现

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

    acc[value] = obj;

    return acc;
  }, {});

用例

const users = [
  { username: 'JX01', status: 'offline' },
  { username: 'yazeedBee', status: 'online' }
];

arrayIntoObject('username', users);
/*
{
  JX01: {
    username: 'JX01',
    status: 'offline'
  },
  yazeedBee: { username: 'yazeedBee', status: 'online' }
}
*/

arrayIntoObject('status', users);
/*
{
  offline: {
    username: 'JX01',
    status: 'offline'
  },
  online: { username: 'yazeedBee', status: 'online' }
}
*/

传送门

【译】10分钟学会reduce

【译】使用reduce制作的10个JavaScript实用函数

【译】还来10个使用reduce制作的JavaScript实用函数