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 Ajax.ashx 高效分页实现代码
Oct 20 Javascript
JS焦点图切换,上下翻转
May 12 Javascript
intro.js 页面引导简单用法 分享
Aug 06 Javascript
JavaScript动态插入script的基本思路及实现函数
Nov 11 Javascript
jQuery学习笔记之 Ajax操作篇(一) - 数据加载
Jun 23 Javascript
JavaScript中判断页面关闭、页面刷新的实现代码
Aug 27 Javascript
AngularJS延迟加载html template
Jul 27 Javascript
老生常谈JavaScript 函数表达式
Sep 01 Javascript
利用Node.js对文件进行重命名
Mar 12 Javascript
Vue项目中引入外部文件的方法(css、js、less)
Jul 24 Javascript
js中对象与对象创建方法的各种方法
Feb 27 Javascript
微信小程序视频弹幕发送功能的实现
Dec 28 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
wamp下修改mysql访问密码的解决方法
2013/05/07 PHP
完整删除ecshop中获取店铺信息的API
2014/12/24 PHP
PHP+MySql+jQuery实现的&quot;顶&quot;和&quot;踩&quot;投票功能
2016/05/21 PHP
PHP面向对象程序设计方法实例详解
2016/12/24 PHP
Yii框架用户登录session丢失问题解决方法
2017/01/07 PHP
PHP实现求连续子数组最大和问题2种解决方法
2017/12/26 PHP
php封装db类连接sqlite3数据库的方法实例
2017/12/19 PHP
Laravel自动生成UUID,从建表到使用详解
2019/10/24 PHP
Jquery之美中不足小结
2011/02/16 Javascript
js中的cookie的读写操作示例详解
2014/04/17 Javascript
js 数组去重的四种实用方法
2014/09/09 Javascript
Javascript基础教程之数组 array
2015/01/18 Javascript
Java File类的常用方法总结
2015/03/18 Javascript
利用vue写todolist单页应用
2016/12/15 Javascript
JavaScript实现淘宝京东6位数字支付密码效果
2018/08/18 Javascript
VUE 实现复制内容到剪贴板的两种方法
2019/04/24 Javascript
详解element-ui级联菜单(城市三级联动菜单)和回显问题
2019/10/02 Javascript
[03:47]2015国际邀请赛第三日现场精彩回顾
2015/08/08 DOTA
Python __setattr__、 __getattr__、 __delattr__、__call__用法示例
2015/03/06 Python
浅谈Python类里的__init__方法函数,Python类的构造函数
2016/12/10 Python
python2.7实现FTP文件下载功能
2018/04/15 Python
python实现Virginia无密钥解密
2019/03/20 Python
详解如何减少python内存的消耗
2019/08/09 Python
Python进阶之使用selenium爬取淘宝商品信息功能示例
2019/09/16 Python
详解Django配置JWT认证方式
2020/05/09 Python
Roxy美国官网:澳大利亚冲浪、滑雪健身品牌
2016/07/30 全球购物
Tech21美国/加拿大:英国NO.1防摔保护壳品牌
2018/01/20 全球购物
初三物理教学反思
2014/01/21 职场文书
英语生日邀请函
2014/01/23 职场文书
优秀团支部事迹材料
2014/02/08 职场文书
本科毕业生自荐信
2014/06/02 职场文书
个人遵守党的政治纪律情况对照检查材料思想汇报
2014/09/25 职场文书
2016年大学自主招生自荐信范文
2015/03/24 职场文书
郭明义电影观后感
2015/06/08 职场文书
2016入党积极分子党课学习心得体会
2015/10/09 职场文书
幼师必备:幼儿园期末教师评语50条
2019/11/01 职场文书