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 相关文章推荐
让firefox支持IE的一些方法的javascript扩展函数代码
Jan 02 Javascript
合并table相同单元格的jquery插件分享(很精简)
Jun 20 Javascript
IE8下String的Trim()方法失效的解决方法
Nov 08 Javascript
选择复选框按钮置灰否则按钮可用
May 22 Javascript
js防止DIV布局滚动时闪动的解决方法
Oct 30 Javascript
微信小程序(应用号)开发新闻客户端实例
Oct 24 Javascript
正则中的回溯定义与用法分析【JS与java实现】
Dec 27 Javascript
jQuery实现单击按钮遮罩弹出对话框效果(1)
Feb 20 Javascript
vue学习教程之带你一步步详细解析vue-cli
Dec 26 Javascript
JavaScript设计模式之构造器模式(生成器模式)定义与用法实例分析
Jul 26 Javascript
微信小程序云开发(数据库)详解
May 17 Javascript
细述Javascript的加法运算符的具体使用
Oct 18 Javascript
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
MVC模式的PHP实现
2006/10/09 PHP
php adodb操作mysql数据库
2009/03/19 PHP
晋城吧对DiscuzX进行的前端优化要点
2010/09/05 PHP
浅谈socket同步和异步、阻塞和非阻塞、I/O模型
2016/12/15 PHP
Javascript优化技巧(文件瘦身篇)
2008/01/28 Javascript
基于Jquery的动态添加控件并取值的实现代码
2010/09/24 Javascript
JS判断数组中是否有重复值得三种实用方法
2013/08/16 Javascript
js使用html()或text()方法获取设置p标签的显示的值
2014/08/01 Javascript
使用Chrome调试JavaScript的断点设置和调试技巧
2014/12/16 Javascript
javascript计时器详解
2015/02/28 Javascript
实例讲解jquery与json的结合
2016/01/07 Javascript
基于d3.js实现实时刷新的折线图
2016/08/03 Javascript
JS+jQuery实现注册信息的验证功能
2017/09/26 jQuery
vue-resourc发起异步请求的方法
2020/02/11 Javascript
python中遍历文件的3个方法
2014/09/02 Python
简介Django中内置的一些中间件
2015/07/24 Python
python实现简单神经网络算法
2018/03/10 Python
pandas 读取各种格式文件的方法
2018/06/22 Python
基于Python实现剪切板实时监控方法解析
2019/09/11 Python
详解Python实现进度条的4种方式
2020/01/15 Python
python实现简单俄罗斯方块
2020/03/13 Python
Python如何生成xml文件
2020/06/04 Python
Flask缓存静态文件的具体方法
2020/08/02 Python
Opencv+Python识别PCB板图片的步骤
2021/01/07 Python
CSS3 优势以及网页设计师如何使用CSS3技术
2009/07/29 HTML / CSS
AJAX的优缺点都有什么
2015/08/18 面试题
会计实习自我鉴定
2013/12/04 职场文书
会计学自我鉴定
2014/02/06 职场文书
初三学习决心书
2014/03/11 职场文书
法律系毕业生自荐信范文
2014/03/27 职场文书
小学师德标兵先进事迹材料
2014/05/25 职场文书
幼儿园标语大全
2014/06/19 职场文书
刑事辩护授权委托书格式
2014/10/13 职场文书
pytorch 如何使用float64训练
2021/05/24 Python
Java中PriorityQueue实现最小堆和最大堆的用法
2021/06/27 Java/Android
通过T-SQL语句创建游标与实现数据库加解密功能
2022/03/16 SQL Server