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 相关文章推荐
使用C++为node.js写扩展模块
Apr 22 Javascript
Jquery简单分页实现方法
Jul 24 Javascript
基于jquery实现瀑布流布局
Jun 28 Javascript
javascript原型继承工作原理和实例详解
Apr 07 Javascript
BootStrap.css 在手机端滑动时右侧出现空白的原因及解决办法
Jun 07 Javascript
jquery配合.NET实现点击指定绑定数据并且能够一键下载
Oct 28 Javascript
浅谈js中的变量名和函数名重名
Feb 13 Javascript
微信小程序 UI与容器组件总结
Feb 21 Javascript
Bootstrap按钮组简单实现代码
Mar 06 Javascript
微信小程序实现点击按钮修改字体颜色功能【附demo源码下载】
Dec 05 Javascript
浅谈vue中.vue文件解析流程
Apr 24 Javascript
扫微信小程序码实现网站登陆实现解析
Aug 20 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
如何选购合适的收音机
2021/03/01 无线电
推荐php模板技术[转]
2007/01/04 PHP
PHP中使用虚代理实现延迟加载技术
2014/11/05 PHP
PHP验证终端类型是否为手机的简单实例
2017/02/07 PHP
JS操作XML中DTD介绍及使用方法分析
2019/07/04 PHP
JavaScript Perfection kill 测试及答案
2010/03/23 Javascript
JS正则中的RegExp对象对象
2012/11/07 Javascript
用jquery方法操作radio使其默认选项是否
2013/09/10 Javascript
javascript日期格式化方法汇总
2015/10/04 Javascript
纯javascript响应式树形菜单效果
2015/11/10 Javascript
jQuery实现动态删除LI的方法
2017/05/30 jQuery
关于react-router的几种配置方式详解
2017/07/24 Javascript
[js高手之路]从原型链开始图解继承到组合继承的产生详解
2017/08/28 Javascript
Node.js利用console输出日志文件的方法示例
2018/04/27 Javascript
nodejs实现套接字服务功能详解
2018/06/21 NodeJs
layui table设置前台过滤转义等方法
2018/08/17 Javascript
vue兄弟组件传递数据的实例
2018/09/06 Javascript
uni-app之APP和小程序微信授权方法
2019/05/09 Javascript
vue 路由子组件created和mounted不起作用的解决方法
2019/11/05 Javascript
解决vue字符串换行问题(绝对管用)
2020/08/06 Javascript
python实现感知器算法详解
2017/12/19 Python
微信跳一跳python自动代码解读1.0
2018/01/12 Python
Win10下python3.5和python2.7环境变量配置教程
2018/09/18 Python
Django上线部署之IIS的配置方法
2019/08/22 Python
python conda操作方法
2019/09/11 Python
Python编写一个验证码图片数据标注GUI程序附源码
2019/12/09 Python
在django admin详情表单显示中添加自定义控件的实现
2020/03/11 Python
俄罗斯厨房产品购物网站:COOK HOUSE
2021/03/15 全球购物
描述内存分配方式以及它们的区别
2016/10/15 面试题
什么是数据库锁?Oracle中都有哪些类型的锁?
2015/08/21 面试题
linux面试题参考答案(6)
2014/08/29 面试题
《恐龙》教学反思
2014/04/27 职场文书
2015年毕业生自我鉴定模板
2014/09/19 职场文书
国家税务局领导班子对照检查材料思想汇报
2014/10/04 职场文书
环境卫生整治简报
2015/07/20 职场文书
MySQL Shell import_table数据导入的实现
2021/08/07 MySQL