乐趣区

关于javascript:JavaScript数组reduce函数的5个运用场景分享


theme: channing-cyan

作为前端人,咱们经常以数组的模式获取某种数据列表,并且须要将其转换为其余模式。在 JavaScript 中内置在所有数组中有一种十分弱小的办法是应用 reduce 函数。最早提出是在 ECMAScript 5.1,往年 4 月份 ECMAScript® 2022 中有所定制其应用标准。上面我将介绍它的根本语法和我在应用中实际分享~

语法

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])

reducer 函数接管 4 个参数:Accumulator (acc) (累计器)、Current Value (cur) (以后元素的值)、Current Index (idx) (以后索引)、Source Array (src) (源数组,也就是正在遍历的对象)。

回调函数第一次执行时,accumulator 和 currentValue 的取值有两种状况:如果调用 reduce()时提供了 initialValue,accumulator 取值为 initialValue,currentValue 取数组中的第一个值;如果没有提供 initialValue,那么 accumulator 取数组中的第一个值,currentValue 取数组中的第二个值。

这里要留神的是:

如果数组为空且没有提供 initialValue,会抛出 TypeError。如果数组仅有一个元素(无论地位如何)并且没有提供 initialValue,或者有提供 initialValue 然而数组为空,那么此惟一值将被返回并且 callback 不会被执行

Reduce 不会间接扭转它所调用的对象,然而该对象能够通过调用 callbackfn 来扭转。

如果你有趣味深入研究,更多相干材料能够移步到官网标准文档
它在各大浏览器的兼容性如图~

可能下面的介绍比拟干燥,接下来咱们就进行实际分享吧!

一、计算数组中所有值的总和,或者最值

// 解决总和的累计器
const delTotal = (acc, item) => {return acc + item;};

// 解决最最大值的累计器
const delMax = (acc, item) => {return (acc > item) ? acc : item
};

const data = [1, 2, 3];
const total = data.reduce(delTotal);
const max = data.reduce(delMax);

console.log("The sum is:", total); //The sum is: 6
console.log("The max is:", max); //The max is: 3
console.log("data:", data); //data:  [1, 2, 3]

对象数组的操作也是如此,留神如果要解决对象数组, 那对象数组中蕴含的值必须提供初始值,以便各个 item 正确通过你的函数~

二、数组去重

const numberArray = [1,3,4,5,4,5,3,4]
const stringArray = ['a', 'b', 'a', 'b', 'c', 'e', 'e']

const delRepetition = (accumulator, currentValue)=> {if (accumulator.indexOf(currentValue) === -1) {accumulator.push(currentValue)
  }
  return accumulator
}

const repNumberArray = numberArray.reduce(delRepetition,[])
const repStringArray = stringArray.reduce(delRepetition,[])

console.log("The repNumberArray is:", repNumberArray); //The repNumberArray is: [1, 3, 4, 5]
console.log("The repStringArray is:", repStringArray); //The repStringArray is: ["a", "b", "c", "e"]

数组去重的形式很多,这种可能不是最佳的,然而也是一种思路。如果你正在应用一个能够兼容SetArray.from() 的环境,你能够应用let orderedArray = Array.from(new Set(myArray)); 来取得一个去重的数组~

三、将二维数组转化为一维

const flattened = [[0, 1], [2, 3], [4, 5]].reduce(( acc, cur) => acc.concat(cur),
 []);

console.log("flattened:", flattened); //flattened: [0, 1, 2, 3, 4, 5]

附带挑战:如何应用 array.reduce()办法把多维数组转化为一维数组?能够在上面的评论中写下您的解决方案~

四、计算数组中每个元素呈现的次数

统计呈现次数这个场景,也很常见,比方投票统计,上面模仿一个前端框架应用投票统计



const initialValue = {};

const reducer = (tally, vote) => {if (!tally[vote]) {tally[vote] = 1;
  } else {tally[vote] = tally[vote] + 1;
  }
  return tally;
};

const votes = [
  "vue",
  "react",
  "angular",
  "vue",
  "react",
  "angular",
  "vue",
  "react",
  "vue"
];
const result = votes.reduce(reducer, initialValue);

console.log("Result:", result)  // Result:  {vue: 4, react: 3, angular: 2}
console.log("Vue:", result.vue) // Vue:  4
console.log("React:", result.react) // React:  3

相似的,也能够解决按属性对 object 分类

五、过滤和映射大数据集,性能更佳

咱们都晓得过滤数组,JavaScript 提供了一种对数组对象进行过滤的 filter() 办法,上面咱们举个例子,对一个大数据数组(100 万个数据)中筛选出所有偶数项,来比照性能

const bigData = [];
for (var i = 0; i < 1000000; i++) {bigData[i] = i;
}

const filterBegin = Date.now()
var filterMappedBigData = bigData.filter((value)=> {return value % 2 === 0;})

const filterEnd = Date.now()
const filtertimeSpent = (filterEnd-filterBegin)/1000 + "s";


const reducedBegin=Date.now();
var reducedBigData = bigData.reduce((acc, value)=> {if (value % 2 === 0) {acc.push(value);
  }
  return acc;
}, []);
const reducedEnd = Date.now();
const reducedtimeSpent = (reducedEnd-reducedBegin)/1000 + "s";


console.log("filtered Big Data:", filtertimeSpent)
console.log("reduced Big Data:", reducedtimeSpent)

在控制台中, 咱们能够看到 filter() 花了 25 毫秒,reduced()花了 20 毫秒,可能你在本地环境测,数据有差别,然而 reduced() 在耗时少, 当然感兴趣的同学,也能够也拿 map() 做试验, 你会发现在解决大数据,reduced()在耗时上都比他们少!

filtered Big Data: 0.025 s
reduced Big Data: 0.020 s

如果你对过滤的数据在别离进行操作的话,耗时这块体现的更显著。如果咱们要解决大量数据信息,那么理解 reduce()函数能够将所有这些操作合并在一起,从而极大地提高性能,这将十分有帮忙~

最初

本文从语法到实际分享了一些我在理论开发中 reduce()函数应用的技巧,心愿有点抛砖引玉的作用,当然它还有很多能够联合利用的场景,比方编写函数,查看嵌套对象等等~,也期待评论区你的分享~

退出移动版