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 相关文章推荐
ExtJS 2.0实用简明教程之应用ExtJS
Apr 29 Javascript
JS字符串拼接在ie中都报错的解决方法
Mar 27 Javascript
Javascript基础教程之数组 array
Jan 18 Javascript
readonly和disabled属性的区别
Jul 26 Javascript
Angularjs的Controller间通信机制实例分析
Nov 07 Javascript
Js apply方法详解
Feb 16 Javascript
基于JavaScript实现数码时钟效果
Mar 30 Javascript
js实现扫雷小程序的示例代码
Sep 27 Javascript
bootstrap treeview 扩展addNode方法动态添加子节点的方法
Nov 21 Javascript
VUE v-model表单数据双向绑定完整示例
Jan 21 Javascript
Vue引入Stylus知识点总结
Jan 16 Javascript
javascript 设计模式之组合模式原理与应用详解
Apr 08 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
全国FM电台频率大全 - 15 山东省
2020/03/11 无线电
smarty中先strip_tags过滤html标签后truncate截取文章运用
2010/10/25 PHP
PHP CURL实现模拟登陆并上传文件操作示例
2020/01/02 PHP
获取DOM对象的几种扩展及简写
2006/10/09 Javascript
Visual Studio中的jQuery智能提示设置方法
2010/03/27 Javascript
js 多种变量定义(对象直接量,数组直接量和函数直接量)
2010/05/24 Javascript
JQuery实现用户名无刷新验证的小例子
2013/03/22 Javascript
javascript动态添加样式(行内式/嵌入式/外链式等规则)
2013/06/24 Javascript
table对象中的insertRow与deleteRow使用示例
2014/01/26 Javascript
浅谈JavaScript字符集
2014/05/22 Javascript
使用jquery.upload.js实现异步上传示例代码
2014/07/29 Javascript
Bootstrap模态框水平垂直居中与增加拖拽功能
2016/11/09 Javascript
ES6新特性一: let和const命令详解
2017/04/20 Javascript
详解vue-cli开发环境跨域问题解决方案
2017/06/06 Javascript
浅谈Angular文字折叠展开组件的原理分析
2017/11/24 Javascript
如何制作一个Node命令行图像识别工具
2018/12/12 Javascript
vue使用localStorage保存登录信息 适用于移动端、PC端
2019/05/27 Javascript
利用Python破解验证码实例详解
2016/12/08 Python
Python 实现淘宝秒杀的示例代码
2018/01/02 Python
python numpy元素的区间查找方法
2018/11/14 Python
python统计字符的个数代码实例
2020/02/07 Python
python实现人脸签到系统
2020/04/13 Python
Python 多进程、多线程效率对比
2020/11/19 Python
将不规则的Python多维数组拉平到一维的方法实现
2021/01/11 Python
expedia比利时:预订航班+酒店并省钱
2018/07/13 全球购物
财务会计自荐信范文
2014/02/21 职场文书
党性锻炼的心得体会
2014/09/03 职场文书
刑事辩护授权委托书
2014/09/13 职场文书
党员教师个人对照检查材料(群众路线)
2014/09/26 职场文书
初中生300字旷课检讨书
2014/11/19 职场文书
乐山大佛导游词
2015/02/02 职场文书
药店营业员岗位职责
2015/04/14 职场文书
谢师宴学生答谢词
2015/09/30 职场文书
MySQL令人咋舌的隐式转换
2021/04/05 MySQL
python百行代码实现汉服圈图片爬取
2021/11/23 Python
Python实现对齐打印 format函数的用法
2022/04/28 Python