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 相关文章推荐
js实现快速分享功能(你的文章分享工具)
Jun 25 Javascript
使用原生js实现页面蒙灰(mask)效果示例代码
Jun 20 Javascript
jQuery中slice()方法用法实例
Jan 07 Javascript
JavaSacript中charCodeAt()方法的使用详解
Jun 05 Javascript
JavaScript常用标签和方法总结
Sep 01 Javascript
jQuery实现圣诞节礼物动画案例解析
Dec 25 Javascript
vue双向绑定简要分析
Mar 23 Javascript
AngularJS实现的base64编码与解码功能示例
May 17 Javascript
jQuery UI实现动画效果代码分享
Aug 19 jQuery
浅谈Vue SSR中的Bundle的具有使用
Nov 21 Javascript
如何利用Node.js与JSON搭建简单的动态服务器
Jun 16 Javascript
vue中实现弹出层动画效果的示例代码
Sep 25 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
5.PHP的其他功能
2006/10/09 PHP
php操作mongoDB实例分析
2014/12/29 PHP
Script标签与访问HTML页面详解
2014/01/10 Javascript
jQuery选择器源码解读(三):tokenize方法
2015/03/31 Javascript
基于jquery实现图片相关操作(重绘、获取尺寸、调整大小、缩放)
2015/12/25 Javascript
JavaScript的this关键字的理解
2016/06/18 Javascript
详解用webpack2.0构建vue2.0超详细精简版
2017/04/05 Javascript
jQuery实现火车票买票城市选择切换功能
2017/09/15 jQuery
JavaScript实现简单生成随机颜色的方法
2017/09/21 Javascript
原生JS实现DOM加载完成马上执行JS代码的方法
2018/09/07 Javascript
详解vue-router数据加载与缓存使用总结
2018/10/29 Javascript
elementui更改el-dialog关闭按钮的图标d的示例代码
2020/08/04 Javascript
python格式化字符串实例总结
2014/09/28 Python
Python THREADING模块中的JOIN()方法深入理解
2015/02/18 Python
Python的gevent框架的入门教程
2015/04/29 Python
python使用smtplib模块通过gmail实现邮件发送的方法
2015/05/08 Python
numpy数组拼接简单示例
2017/12/15 Python
Python内置模块logging用法实例分析
2018/02/12 Python
python opencv之SIFT算法示例
2018/02/24 Python
Python面向对象之类和对象实例详解
2018/12/10 Python
Python函数的默认参数设计示例详解
2019/12/01 Python
Pytorch to(device)用法
2020/01/08 Python
Python 剪绳子的多种思路实现(动态规划和贪心)
2020/02/24 Python
女士时装鞋:Chinese Laundry
2018/08/29 全球购物
总经理任命书
2014/03/29 职场文书
农村葬礼主持词
2014/03/31 职场文书
初中班主任评语
2014/04/24 职场文书
工商管理专业自荐信
2014/06/03 职场文书
明星员工获奖感言
2014/08/14 职场文书
祖国在我心中演讲稿(小学生)
2014/09/23 职场文书
党员自我剖析材料范文
2014/10/06 职场文书
2014年物流工作总结
2014/11/25 职场文书
故宫英文导游词
2015/01/31 职场文书
2015年街道除四害工作总结
2015/05/15 职场文书
Python 读写 Matlab Mat 格式数据的操作
2021/05/19 Python
JS前端使用canvas实现扩展物体类和事件派发
2022/08/05 Javascript