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编程起步(第二课)
Jan 10 Javascript
jQuery实现简单网页遮罩层/弹出层效果兼容IE6、IE7
Jun 16 Javascript
jQuery中:text选择器用法实例
Jan 03 Javascript
28个常用JavaScript方法集锦
Jan 14 Javascript
jQuery实现按钮点击遮罩加载及处理完后恢复的效果
Jun 07 Javascript
JavaScript必知必会(九)function 说起 闭包问题
Jun 08 Javascript
div实现自适应高度的textarea实现angular双向绑定
Jan 08 Javascript
简单实现js点击展开二级菜单功能
May 16 Javascript
前端构建工具之gulp的配置与搭建详解
Jun 12 Javascript
Javascript实现base64的加密解密方法示例
Jun 27 Javascript
Node.js中console.log()输出彩色字体的方法示例
Dec 01 Javascript
京东优选小程序的实现代码示例
Feb 25 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
PHP 事件机制(2)
2011/03/23 PHP
PHP图片自动裁切应付不同尺寸的显示
2014/10/16 PHP
PHP读取word文档的方法分析【基于COM组件】
2017/08/01 PHP
Laravel构建即时应用的一种实现方法详解
2017/08/31 PHP
PHP判断一个变量是否为整数、正整数的方法示例
2019/09/11 PHP
JQuery 学习笔记 选择器之三
2009/07/23 Javascript
将jQuery应用于login页面的问题及解决
2009/10/17 Javascript
JavaScript二维数组实现的省市联动菜单
2014/05/08 Javascript
JavaScript中this关键词的使用技巧、工作原理以及注意事项
2014/05/20 Javascript
jquery实现表单验证简单实例演示
2015/11/23 Javascript
jQuery EasyUI 获取tabs的实例解析
2016/12/06 Javascript
jQuery使用siblings获取某元素所有同辈(兄弟姐妹)元素用法示例
2017/01/30 Javascript
微信小程序上传图片到服务器实例代码
2017/11/07 Javascript
vue 使用eventBus实现同级组件的通讯
2018/03/02 Javascript
Vue.js+Layer表格数据绑定与实现更新的实例
2018/03/07 Javascript
详解Vue结合后台的列表增删改案例
2018/08/21 Javascript
JSON生成Form表单的方法示例
2018/11/21 Javascript
微信小程序解析富文本过程详解
2019/07/13 Javascript
使用TS来编写express服务器的方法步骤
2020/10/29 Javascript
[43:03]LGD vs Newbee 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
python3.5使用tkinter制作记事本
2016/06/20 Python
Python语言描述最大连续子序列和
2017/12/05 Python
快速了解Python相对导入
2018/01/12 Python
python 对给定可迭代集合统计出现频率,并排序的方法
2018/10/18 Python
python中partial()基础用法说明
2018/12/30 Python
详解使用PyInstaller将Pygame库编写的小游戏程序打包为exe文件
2019/08/23 Python
Python如何获取Win7,Win10系统缩放大小
2020/01/10 Python
Django --Xadmin 判断登录者身份实例
2020/07/03 Python
python解包用法详解
2021/02/17 Python
Python3爬虫RedisDump的安装步骤
2021/02/20 Python
html5 localStorage本地存储_动力节点Java学院整理
2017/07/06 HTML / CSS
HTML5移动端开发中的Viewport标签及相关CSS用法解析
2016/04/15 HTML / CSS
TecoBuy澳大利亚:在线电子和小工具商店
2020/06/25 全球购物
药店促销活动策划方案
2014/08/24 职场文书
银行党员批评与自我批评
2014/10/15 职场文书
初三毕业评语
2014/12/26 职场文书