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 相关文章推荐
jQuery对表单的操作代码集合
Apr 06 Javascript
javascript查找字符串中出现最多的字符和次数的小例子
Oct 29 Javascript
SeaJS入门教程系列之SeaJS介绍(一)
Mar 03 Javascript
js Dialog 去掉右上角的X关闭功能
Apr 23 Javascript
javascript中动态函数用法实例分析
May 14 Javascript
JS实现灵巧的下拉导航效果代码
Aug 25 Javascript
JQuery标签页效果实例详解
Dec 24 Javascript
微信小程序 教程之注册程序
Oct 17 Javascript
360提示[高危]使用存在漏洞的JQuery版本的解决方法
Oct 27 jQuery
详解微信UnionID作用
May 15 Javascript
在vue中实现清除echarts上次保留的数据(亲测有效)
Sep 09 Javascript
Vue.js桌面端自定义滚动条组件之美化滚动条VScroll
Dec 01 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
php json_encode()函数返回json数据实例代码
2014/10/10 PHP
php抽象类使用要点与注意事项分析
2015/02/09 PHP
如何在旧的PHP系统中使用PHP 5.3之后的库
2015/12/02 PHP
php同时使用session和cookie来保存用户登录信息的实现代码
2016/05/13 PHP
php报错502badgateway解决方法
2019/10/11 PHP
javascript 选择文件夹对话框(web)
2009/07/07 Javascript
javascript类继承机制的原理分析
2009/09/12 Javascript
IE event.srcElement和FF event.target 功能比较
2010/03/01 Javascript
javascript 仿QQ滑动菜单效果代码
2010/09/03 Javascript
jQuery setTimeout()函数使用方法
2013/04/07 Javascript
IE下Ajax缓存问题的快速解决方法(get方式)
2014/01/09 Javascript
Highcharts使用简例及异步动态读取数据
2015/12/30 Javascript
javascript的几种写法总结
2016/09/30 Javascript
浅谈layer的iframe弹窗给里面的标签赋值的问题
2016/11/10 Javascript
vue2.0父子组件及非父子组件之间的通信方法
2017/01/21 Javascript
Express本地测试HTTPS的示例代码
2018/06/06 Javascript
node.js中TCP Socket多进程间的消息推送示例详解
2018/07/10 Javascript
Vue.js 中的 v-cloak 指令及使用详解
2018/11/19 Javascript
基于mpvue小程序使用echarts画折线图的方法示例
2019/04/24 Javascript
echarts统计x轴区间的数值实例代码详解
2019/07/07 Javascript
vue-model实现简易计算器
2020/08/17 Javascript
vue created钩子函数与mounted钩子函数的用法区别
2020/11/05 Javascript
VUE实现吸底按钮
2021/03/04 Vue.js
利用 Monkey 命令操作屏幕快速滑动
2016/12/07 Python
python解析基于xml格式的日志文件
2017/02/25 Python
Python标准库之collections包的使用教程
2017/04/27 Python
python+requests+unittest API接口测试实例(详解)
2017/06/10 Python
ORM Django 终端打印 SQL 语句实现解析
2019/08/09 Python
CSS3 RGBA色彩模式使用实例讲解
2016/04/26 HTML / CSS
html5借用repeating-linear-gradient实现一把刻度尺(ruler)
2019/09/09 HTML / CSS
迪士尼法国在线商店:shopDisney FR
2020/12/03 全球购物
校园文明倡议书
2014/05/16 职场文书
九一八事变纪念日演讲稿
2014/09/14 职场文书
人事专员岗位职责
2015/02/03 职场文书
通知的格式范文
2015/04/27 职场文书
Redis实现主从复制方式(Master&Slave)
2022/06/21 Redis