JavaScript中10个Reduce常用场景技巧


Posted in Javascript onJune 21, 2022

不知道大家平常用 Reduce 多不多,反正本瓜用的不多。但实际上,Reduce 能做的,比我们能想到的要多得多,本篇带来 10 个Reduce 常用场景和技巧,一定有你不知道~

冲ヾ(◍°∇°◍)ノ゙

累加/累积

累加我们可能是最熟悉 Reduce 的一种用法,除此之外,还可以用做累积。

// adder
const sum = (...nums) => {
  return nums.reduce((sum, num) => sum + num);
};
console.log(sum(1, 2, 3, 4, 10)); // 20
// accumulator
const accumulator = (...nums) => {
  return nums.reduce((acc, num) => acc * num);
};
console.log(accumulator(1, 2, 3)); // 6

求最大/最小值

如果你用原生 api 求最大/最小值,无可厚非,Reduce 也能实现同样的效果。

const array = [-1, 10, 6, 5];
const max = Math.max(...array); // 10
const min = Math.min(...array); // -1
const array = [-1, 10, 6, 5];
const max = array.reduce((max, num) => (max > num ? max : num));
const min = array.reduce((min, num) => (min < num ? min : num));

格式化搜索参数

获取 url 上的参数是我们经常面临的需求,用 forEach 遍历可以,用 Reduce 累加更可以,这样可以减少声明 query 对象。

// url https://qianlongo.github.io/vue-demos/dist/index.html?name=fatfish&age=100#/home
// format the search parameters
{
  "name": "fatfish",
  "age": "100"
}
const parseQuery = () => {
  const search = window.location.search;
  let query = {};
  search
    .slice(1)
    .split("&")
    .forEach((it) => {
      const [key, value] = it.split("=");
      query[key] = decodeURIComponent(value);
    });
  return query;
};
const parseQuery = () => {
  const search = window.location.search;
  return search
    .slice(1)
    .split("&")
    .reduce((query, it) => {
      const [key, value] = it.split("=");
      query[key] = decodeURIComponent(value);
      return query;
    }, {});
};

反序列化搜索参数

有了获取 url 参数,就有把参数重新挂在到 url 上面,好用,收藏。

const searchObj = {
  name: "fatfish",
  age: 100,
  // ...
};
const link = `https://medium.com/?name=${searchObj.name}&age=${searchObj.age}`;
// https://medium.com/?name=fatfish&age=100
const stringifySearch = (search = {}) => {
  return Object.entries(search)
    .reduce(
      (t, v) => `${t}${v[0]}=${encodeURIComponent(v[1])}&`,
      Object.keys(search).length ? "?" : ""
    )
    .replace(/&$/, "");
};
const search = stringifySearch({
  name: "fatfish",
  age: 100,
});
const link = `https://medium.com/${search}`;
console.log(link); // https://medium.com/?name=fatfish&age=100

拉平嵌套数组

我们都会用 .flat(Infinity) 无限拉平所有多维数组成一维数组,只用 reduce 和 flat 也是可以做到这一点的。

const array = [1, [2, [3, [4, [5]]]]];
// expected output [ 1, 2, 3, 4, 5 ]
const flatArray = array.flat(Infinity); // [1, 2, 3, 4, 5]
const flat = (array) => {
  return array.reduce(
    (acc, it) => acc.concat(Array.isArray(it) ? flat(it) : it),
    []
  );
};
const array = [1, [2, [3, [4, [5]]]]];
const flatArray = flat(array); // [1, 2, 3, 4, 5]

实现 flat

如果想实现 flat,用 reduce 没错了,又是一个手写原生 api 内部实现,妥妥的刚。

// Expand one layer by default
Array.prototype.flat2 = function (n = 1) {
  const len = this.length
  let count = 0
  let current = this
  if (!len || n === 0) {
    return current
  }
  // Confirm whether there are array items in current
  const hasArray = () => current.some((it) => Array.isArray(it))
  // Expand one layer after each cycle
  while (count++ < n && hasArray()) {
    current = current.reduce((result, it) => {
      result = result.concat(it)
      return result
    }, [])
  }
  return current
}
const array = [ 1, [ 2, [ 3, [ 4, [ 5 ] ] ] ] ]
// Expand one layer
console.log(array.flat()) // [ 1, 2, [ 3, [ 4, [ 5 ] ] ] ] 
console.log(array.flat2()) // [ 1, 2, [ 3, [ 4, [ 5 ] ] ] ] 
// Expand all
console.log(array.flat(Infinity))
console.log(array.flat2(Infinity))

数组去重

数组去重,用 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 ], [])

数组计数

将数组的项进行计数,返回一个 map,分别是每个项重复的次数,reduce 一行代码搞定,收藏!

const count = (array) => {
  return 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(7) {1 => 2, 2 => 2, -1 => 1, 0 => 1, '0' => 1, …}

获取对象多个属性

获取对象的多个属性,然后赋给新的对象,比较笨的做法如下:

// There is an object with many properties
const obj = {
  a: 1,
  b: 2,
  c: 3,
  d: 4,
  e: 5
  // ...
}
// We just want to get some properties above it to create a new object
const newObj = {
  a: obj.a,
  b: obj.b,
  c: obj.c,
  d: obj.d
  // ...
}
// Do you think this is too inefficient?

用 Reduce 这样解决,就显得明智了许多:

const getObjectKeys = (obj = {}, keys = []) => {
  return 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)

反转字符串

除了 reverse 做数组的翻转,Reduce 也可以,再加上 split,就可以反转字符串啦。

const reverseString = (string) => {
  return string.split("").reduceRight((acc, s) => acc + s)
}
const string = 'fatfish'
console.log(reverseString(string)) // hsiftaf

以上就是JavaScript中Reduce10个常用场景和技巧的详细内容,更多关于JavaScript Reduce技巧的资料请关注三水点靠木其它相关文章!


Tags in this post...

Javascript 相关文章推荐
JavaScript 快捷键设置实现代码
Mar 13 Javascript
javascript 拷贝节点cloneNode()使用介绍
Apr 03 Javascript
jQuery中attr()和prop()在修改checked属性时的区别
Jul 18 Javascript
js与jquery分别实现tab标签页功能的方法
Nov 18 Javascript
jQuery模拟爆炸倒计时功能实例代码
Aug 21 jQuery
浅谈JavaScript find 方法不支持IE的问题
Sep 28 Javascript
vue父组件向子组件动态传值的两种方法
Nov 11 Javascript
解决vue axios的封装 请求状态的错误提示问题
Sep 25 Javascript
解决node终端下运行js文件不支持ES6语法
Apr 04 Javascript
vue 百度地图(vue-baidu-map)绘制方向箭头折线实例代码详解
Apr 28 Javascript
vue基于Echarts的拖拽数据可视化功能实现
Dec 04 Vue.js
vue keep-alive的简单总结
Jan 25 Vue.js
js前端面试常见浏览器缓存强缓存及协商缓存实例
Jun 21 #Javascript
JavaScript前端面试组合函数
Jun 21 #Javascript
Vue2项目中对百度地图的封装使用详解
JavaScript原型链中函数和对象的理解
JS精髓原型链继承及构造函数继承问题纠正
Jun 16 #Javascript
5个实用的JavaScript新特性
Jun 16 #Javascript
字节飞书面试promise.all实现示例
Jun 16 #Javascript
You might like
各种咖啡的英文名子是什么
2021/03/03 新手入门
PHP获取网址的顶级域名函数代码
2012/09/24 PHP
探讨如何在PHP开启gzip页面压缩实例
2013/06/09 PHP
php验证邮箱和ip地址最简单方法汇总
2015/10/30 PHP
jquery ajax提交表单数据的两种实现方法
2010/04/29 Javascript
getElementByIdx_x js自定义getElementById函数
2012/01/24 Javascript
JS实现局部选择打印和局部不选择打印
2014/04/03 Javascript
动态加载iframe时get请求传递中文参数乱码解决方法
2014/05/07 Javascript
script标签属性用type还是language
2015/01/21 Javascript
Node.js事件驱动
2015/06/18 Javascript
Js 获取、判断浏览器版本信息的简单方法
2016/08/08 Javascript
Javascript单例模式的介绍和实例
2016/10/08 Javascript
纯js代码生成可搜索选择下拉列表的实例
2018/01/11 Javascript
vue 自定义 select内置组件
2018/04/10 Javascript
JS实现获取word文档内容并输出显示到html页面示例
2018/06/23 Javascript
vue中typescript装饰器的使用方法超实用教程
2019/06/17 Javascript
手把手带你搭建一个node cli的方法示例
2020/08/07 Javascript
nodejs处理tcp连接的核心流程
2021/02/26 NodeJs
python多进程操作实例
2014/11/21 Python
python函数局部变量用法实例分析
2015/08/04 Python
Python实现扣除个人税后的工资计算器示例
2018/03/26 Python
对python GUI实现完美进度条的示例详解
2018/12/13 Python
python机器学习库scikit-learn:SVR的基本应用
2019/06/26 Python
python中sort和sorted排序的实例方法
2019/08/26 Python
python爬虫爬取笔趣网小说网站过程图解
2019/11/18 Python
Python实现树莓派摄像头持续录像并传送到主机的步骤
2020/11/30 Python
pandas apply使用多列计算生成新的列实现示例
2021/02/24 Python
比利时香水网上商店:NOTINO
2018/03/28 全球购物
联想印度官方网上商店:Lenovo India
2019/08/24 全球购物
科颜氏英国官网:Kiehl’s英国
2019/11/20 全球购物
公司财务自我评价分享
2013/12/17 职场文书
彩妆大赛策划方案
2014/05/13 职场文书
贷款委托书怎么写
2014/08/02 职场文书
工作会议简报
2015/07/20 职场文书
教师远程培训心得体会
2016/01/09 职场文书
《地。-关于地球的运动-》单行本第七集上市,小说家朝井辽献上期待又害怕的推荐文
2022/03/31 日漫