首页 > 其他分享 >10 个值得掌握的 reduce 技巧

10 个值得掌握的 reduce 技巧

时间:2023-03-03 12:34:21浏览次数:52  
标签:10 const 技巧 max reduce console array log

10 个值得掌握的 reduce 技巧

10 个值得掌握的 reduce 技巧

DevPoint DevPoint 深耕WEB开发10+年,拥有一颗工匠的心   ​ 展开目录  

作为一个前端开发者,一定有接触过 reduce 函数,它是一个强大而实用的数组方法,熟练掌握 reduce 的使用可以在开发中提高开发效率和代码质量。本文介绍的 reduce 的 10 个技巧值得拥有,可以让你少写很多代码!

图灵程序设计丛书:数据结构与算法JavaScript描述(图 京东 ¥42.60 去购买​

reduce 方法在数组的每个元素上执行提供的回调函数迭代器。它传入前一个元素计算的返回值,结果是单个值,它是在数组的所有元素上运行迭代器的结果。

迭代器函数逐个遍历数组的元素,在每一步中,迭代器函数将当前数组值添加到上一步的结果中,直到没有更多元素要添加。

语法

参数包含回调函数和可选的初始值,如下:

array.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
  • callback(必须):执行数组中每个值(如果没有提供 initialValue 则第一个值除外)的 reducer 函数,包含四个参数
    • accumulator(必须):累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,初始值可以通过initialValue定义,默认为数组的第一个元素值,累加器将保留上一个操作的值,就像静态变量一样
    • currentValue(必须):数组中正在处理的元素
    • index(可选):数组中正在处理的当前元素的索引。 如果提供了 initialValue,则起始索引号为 0,否则从索引 1 起始。 > 注意:如果没有提供 initialValuereduce 会从索引 1 的地方开始执行 callback 方法,跳过第一个索引。如果提供 initialValue,从索引 0 开始。
    • array(可选):调用 reduce() 的数组
  • initialValue(可选):作为第一次调用 callback 函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用reduce将报错。

1. 计算数组的最大值和最小值

有很多种方式可以获取数组的最大值或最小值?

使用 Math.max 和 Math.min

使用 Math 的 API 是最简单的方式。

const arrayNumbers = [-1, 10, 6, 5, -3];
const max = Math.max(...arrayNumbers); // 10
const min = Math.min(...arrayNumbers); // -3
console.log(`max=${max}`); // max=10
console.log(`min=${min}`); // min=-3

使用 reduce

一行代码,就可以实现与 Math 的 API 相同的效果。

const arrayNumbers = [-1, 10, 6, 5, -3];
const getMax = (array) => array.reduce((max, num) => (max > num ? max : num));
const getMin = (array) => array.reduce((max, num) => (max < num ? max : num));

const max = getMax(arrayNumbers); // 10
const min = getMin(arrayNumbers); // -3
console.log(`max=${max}`); // max=10
console.log(`min=${min}`); // min=-3

或者写成一个函数:

const arrayNumbers = [-1, 10, 6, 5, -3];

const getMaxOrMin = (array, type = "min") =>
    type === "max"
        ? array.reduce((max, num) => (max > num ? max : num))
        : array.reduce((max, num) => (max < num ? max : num));

const max = getMaxOrMin(arrayNumbers, "max"); // 10
const min = getMaxOrMin(arrayNumbers, "min"); // -3
console.log(`max=${max}`); // max=10
console.log(`min=${min}`); // min=-3

2. 数组求和和累加器

使用 reduce ,可以轻松实现多个数相加或累加的功能。

// 数组求和
const sum = (...nums) => {
    return nums.reduce((sum, num) => sum + num);
};

// 累加器
const accumulator = (...nums) => {
    return nums.reduce((acc, num) => acc * num);
};
const arrayNumbers = [1, 3, 5];

console.log(accumulator(1, 2, 3)); // 6
console.log(accumulator(...arrayNumbers)); // 15

console.log(sum(1, 2, 3, 4, 5)); // 15
console.log(sum(...arrayNumbers)); // 9

3. 格式化搜索参数

获取 URL 种的搜索参数是经常要处理的功能。

// url https://www.devpoint.cn/index.shtml?name=devpoint&id=100
// 格式化 search parameters
{
    name: "devpoint",
    id: "100",
}

常规方式

这是大多数人使用它的方式。

const parseQuery = (search = window.location.search) => {
    const query = {};
    search
        .slice(1)
        .split("&")
        .forEach((it) => {
            const [key, value] = it.split("=");
            query[key] = decodeURIComponent(value);
        });
    return query;
};
console.log(parseQuery("?name=devpoint&id=100")); // { name: 'devpoint', id: '100' }

使用 reduce

const parseQuery = (search = window.location.search) =>
    search
        .replace(/(^\?)|(&$)/g, "")
        .split("&")
        .reduce((query, it) => {
            const [key, value] = it.split("=");
            query[key] = decodeURIComponent(value);
            return query;
        }, {});

console.log(parseQuery("?name=devpoint&id=100")); // { name: 'devpoint', id: '100' }

4. 反序列化搜索参数

当要跳转到某个链接并为其添加一些搜索参数时,手动拼接的方式不是很方便。如果要串联的参数很多,那将是一场灾难。

const searchObj = {
    name: "devpoint",
    id: 100,
    // ...
};
const strLink = `https://www.devpoint.cn/index.shtml?name=${searchObj.name}&age=${searchObj.id}`;
console.log(strLink); // https://www.devpoint.cn/index.shtml?name=devpoint&age=100

reduce 可以轻松解决这个问题。

const searchObj = {
    name: "devpoint",
    id: 100,
    // ...
};
const stringifySearch = (search = {}) =>
    Object.entries(search)
        .reduce(
            (t, v) => `${t}${v[0]}=${encodeURIComponent(v[1])}&`,
            Object.keys(search).length ? "?" : ""
        )
        .replace(/&$/, "");

const strLink = `https://www.devpoint.cn/index.shtml${stringifySearch(
    searchObj
)}`;
console.log(strLink); // https://www.devpoint.cn/index.shtml?name=devpoint&age=100

5. 展平多层嵌套数组

如何展平多层嵌套数组吗?

const array = [1, [2, [3, [4, [5]]]]];
const flatArray = array.flat(Infinity);

console.log(flatArray); // [ 1, 2, 3, 4, 5 ]

如果运行环境支持方法 flat ,则可以直接用,如果不支持,使用 reduce 也可以实现和flat一样的功能。

const array = [1, [2, [3, [4, [5]]]]];

const flat = (arrayNumbers) =>
    arrayNumbers.reduce(
        (acc, it) => acc.concat(Array.isArray(it) ? flat(it) : it),
        []
    );
const flatArray = flat(array);

console.log(flatArray); // [ 1, 2, 3, 4, 5 ]

6. 计算数组成员的数量

如何计算数组中每个成员的个数?即计算重复元素的个数。

const count = (array) =>
    array.reduce(
        (acc, it) => (acc.set(it, (acc.get(it) || 0) + 1), acc),
        new Map()
    );
const array = [1, 2, 1, 2, -1, 0, "0", 10, "10"];
console.log(count(array));

这里使用了数据类型 Map ,关于 JavaScript 的这个数据类型,有兴趣可以阅读下文:

DevPoint:JavaScript 数据结构之 Map5 赞同 · 0 评论文章

上面代码的输出结果如下:

Map(7) {
  1 => 2,
  2 => 2,
  -1 => 1,
  0 => 1,
  '0' => 1,
  10 => 1,
  '10' => 1
}

7. 获取一个对象的多个属性

这是一个项目开发中比较常遇见的场景。通过 API 获取后端数据,前端很多时候只需要取其中部分的数据。

// 一个有很多属性的对象
const obj = {
    a: 1,
    b: 2,
    c: 3,
    d: 4,
    e: 5,
    // ...
};
// 只是想得到它上面的一些属性来创建一个新的对象
const newObj = {
    a: obj.a,
    b: obj.b,
    c: obj.c,
    d: obj.d,
    // ...
};
这个时候可以使用 reduce 来解决。
/**
 *
 * @param {*} obj 原始对象
 * @param {*} keys 需要获取的属性值列表,数组形式
 * @returns
 */
const getObjectKeys = (obj = {}, keys = []) =>
    Object.keys(obj).reduce(
        (acc, key) => (keys.includes(key) && (acc[key] = obj[key]), acc),
        {}
    );

const obj = {
    a: 1,
    b: 2,
    c: 3,
    d: 4,
    e: 5,
    // ...
};
const newObj = getObjectKeys(obj, ["a", "b", "c", "d"]);
console.log(newObj); // { a: 1, b: 2, c: 3, d: 4 }

8. 反转字符串

反转字符串是面试中最常问到的 JavaScript 问题之一。

const reverseString = (string) => {
    return string.split("").reduceRight((acc, s) => acc + s);
};
const string = "devpoint";
console.log(reverseString(string)); // tniopved

9. 数组去重

reduce 也很容易实现数组去重。

const array = [1, 2, 1, 2, -1, 10, 11];
const uniqueArray1 = [...new Set(array)];
const uniqueArray2 = array.reduce(
    (acc, it) => (acc.includes(it) ? acc : [...acc, it]),
    []
);

console.log(uniqueArray1); // [ 1, 2, -1, 10, 11 ]
console.log(uniqueArray2); // [ 1, 2, -1, 10, 11 ]

10. 模拟方法 flat

虽然现在的JavaScript有原生方法已经实现了对深度嵌套数组进行扁平化的功能,但是如何才能完整的实现扁平化的功能呢?下面就是使用 reduce 来实现其功能:

// 默认展开一层
Array.prototype.flat2 = function (n = 1) {
    const len = this.length;
    let count = 0;
    let current = this;
    if (!len || n === 0) {
        return current;
    }
    // 确认当前是否有数组项
    const hasArray = () => current.some((it) => Array.isArray(it));
    // 每次循环后展开一层
    while (count++ < n && hasArray()) {
        current = current.reduce((result, it) => result.concat(it), []);
    }
    return current;
};
const array = [1, [2, [3, [4, [5]]]]];
// 展开一层
console.log(array.flat()); // [ 1, 2, [ 3, [ 4, [ 5 ] ] ] ]
console.log(array.flat2()); // [ 1, 2, [ 3, [ 4, [ 5 ] ] ] ]
// 展开所有
console.log(array.flat(Infinity)); // [ 1, 2, 3, 4, 5 ]
console.log(array.flat2(Infinity)); // [ 1, 2, 3, 4, 5 ]

 

编辑于 2023-02-23 09:45・IP 属地广东

标签:10,const,技巧,max,reduce,console,array,log
From: https://www.cnblogs.com/sexintercourse/p/17175174.html

相关文章

  • MyBatis_10(分页插件)
    主题:分页插件一、分页插件使用步骤:1-添加依赖<!--https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper--><dependency> <groupId>com.github......
  • L10_用日语询问某个东西多少钱
    概述动画会话A:たくさんありますね。有好多啊。B:すごいでしょう。これはサラサラヘア。これはツヤが出るティプ很棒吧。这款是让头发顺滑。这款是让头发出......
  • Win10安装WSL
    1.安装Ubuntu(WSL)搜索:打开或关闭Windows勾选重启微软商店搜索安装Ubuntu问题处理Error:0x800701bcWSL2启用虚拟化更新wsl下载:https://wslstor......
  • 10_Spring_CGLIB动态代理
     proxy动态代理面向接口1必须有接口和实现类 2增强接口中定义的方法3只能读取接口中方法的上注解cglib动态代理模式面向父类 packagecom.msb.testCglib;importo......
  • 10_Spring_CGLIB动态代理
     proxy动态代理面向接口1必须有接口和实现类 2增强接口中定义的方法3只能读取接口中方法的上注解cglib动态代理模式面向父类 packagecom.msb.testCglib;importo......
  • msvcr100.dll丢失是什么意思-msvcr100.dll丢失解决方法
    丢失msvcr100.dll或者损坏会导致电脑很多软件跟游戏都无法正常打开运行。还有不少小伙伴不知道怎么修复,小编今天就把修复教程分享给大家;最简单的修复方法电脑开机打开任意一......
  • [转]Windows10下CLion配置说明
    Windows10下CLion配置说明CLion是C/C++的IDE,可以配置多种编译环境,本文以配置MinGW编译环境为例。安装CLion的安装可直接到官网下载ZIP,文件解压后直接运行即可。我在......
  • SQL注入之延时注入(10)
    以下提供两种方式进行延时注入GET/sqli/Less-10/?id=1"+and+sleep(5)--+HTTP/1.1Host:192.168.245.146:6101User-Agent:Mozilla/5.0(X11;Linuxx86_64;rv:102.0......
  • 10_Spring_CGLIB动态代理
    ​ proxy动态代理面向接口1必须有接口和实现类 2增强接口中定义的方法3只能读取接口中方法的上注解cglib动态代理模式面向父类 packagecom.msb.testCglib......
  • 10_Spring_CGLIB动态代理
    ​ proxy动态代理面向接口1必须有接口和实现类 2增强接口中定义的方法3只能读取接口中方法的上注解cglib动态代理模式面向父类 packagecom.msb.testCglib......