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 相关文章推荐
在视频前插入广告
Nov 20 Javascript
JavaScript之自定义类型
May 04 Javascript
把input初始值不写value的具体实现方法
Jul 04 Javascript
json数据与字符串的相互转化示例
Sep 18 Javascript
JSON格式的键盘编码对照表
Jan 29 Javascript
JS 对象(Object)和字符串(String)互转方法
May 20 Javascript
jQuery制作全屏宽度固定高度轮播图(实例讲解)
Jul 08 jQuery
js+html5实现半透明遮罩层弹框效果
Aug 24 Javascript
vue仿淘宝订单状态的tab切换效果
Jun 23 Javascript
微信小程序loading组件显示载入动画用法示例【附源码下载】
Dec 09 Javascript
vue cli3适配所有端方案的实现
Apr 13 Javascript
Vue实现返回顶部按钮实例代码
Oct 21 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页面运行时间的函数介绍
2013/07/01 PHP
本地机apache配置基于域名的虚拟主机详解
2013/08/10 PHP
php用header函数实现301跳转代码实例
2013/11/25 PHP
php array_merge函数使用需要注意的一个问题
2015/03/30 PHP
php用户注册信息验证正则表达式
2015/11/12 PHP
Symfony2框架创建项目与模板设置实例详解
2016/03/17 PHP
Yii1.1中通过Sql查询进行的分页操作方法
2017/03/16 PHP
php实现自定义中奖项数和概率的抽奖函数示例
2017/05/26 PHP
laravel框架中路由设置,路由参数和路由命名实例分析
2019/11/23 PHP
php+mysql+ajax 局部刷新点赞/取消点赞功能(每个账号只点赞一次)
2020/07/24 PHP
JQuery Easyui Tree的oncheck事件实现代码
2010/05/28 Javascript
jquery 图片缩放拖动的简单实例
2014/01/08 Javascript
JavaScript代码实现左右上下自动晃动自动移动
2016/04/08 Javascript
Javascript打印局部页面实例
2016/06/21 Javascript
jquery 抽奖小程序实现代码
2016/10/12 Javascript
详解vue项目首页加载速度优化
2017/10/18 Javascript
NodeJS模块与ES6模块系统语法及注意点详解
2019/01/04 NodeJs
浅谈vue-router路由切换 组件重用挖下的坑
2019/11/01 Javascript
keep-Alive搭配vue-router实现缓存页面效果的示例代码
2020/06/24 Javascript
VUE动态生成word的实现
2020/07/26 Javascript
python使用Plotly绘图工具绘制气泡图
2019/04/01 Python
Python Pandas实现数据分组求平均值并填充nan的示例
2019/07/04 Python
python 自动识别并连接串口的实现
2021/01/19 Python
css3背景图片透明叠加属性cross-fade简介及用法实例
2013/01/08 HTML / CSS
CSS3实现曲线阴影和翘边阴影
2016/05/03 HTML / CSS
婚礼主持结束词
2014/03/13 职场文书
创意广告词
2014/03/17 职场文书
电子装配专业毕业生求职信
2014/04/23 职场文书
学习雷锋标语
2014/06/25 职场文书
投标授权委托书范文
2014/08/02 职场文书
小学生田径运动会广播稿
2014/09/11 职场文书
乡镇党的群众路线教育实践活动总结报告
2014/10/30 职场文书
决心书格式范文
2015/09/23 职场文书
2019幼儿园感恩节活动策划书
2019/11/28 职场文书
Windows下载并安装MySQL8.0.x 版本的完整教程
2022/04/10 MySQL
我国拿下天问一号火星着陆区附近 22 个地理实体命名:平乐、西柏坡、古田、漠河等
2022/04/29 数码科技