jsArray常用API之替代传统fori循环

tech2024-06-26  69

文章目录

前言正文foreacheveryfilterfindmapsomereduce小结 结语

前言

先看看下面这段代码:(重点关注两函数的实现方式,无需细看实现逻辑)

function getAreaSale1(values, areas) { const areaSale = []; areas.forEach(area => { let sum = values.reduce((acc, cur) => { if (cur.area === area) { acc[area] === undefined ? acc[area] = cur.sale : acc[area] += cur.sale; } return acc; }, {}); areaSale.push(sum); }) return areaSale; } function getAreaSale2(values, areas) { const areaSale = []; for (let i = 0; i < areas.length; i++) { let sum = {}; for (let j = 0; j < values.length; j++) { if (values[j].area === areas[i]) { sum[areas[i]] === undefined ? sum[areas[i]] = values[j].sale : sum[areas[i]] += values[j].sale; } } areaSale.push(sum); } return areaSale; } function main() { const values = [ { area: '西安', sale: 123 }, { area: '咸阳', sale: 234 }, { area: '西安', sale: 345 }, { area: '宝鸡', sale: 456 }, { area: '铜川', sale: 567 }, { area: '铜川', sale: 678 }, { area: '宝鸡', sale: 789 }, ] const areas = ['西安', '咸阳', '宝鸡', '铜川']; console.log(getAreaSale2(values, areas)); }

getAreaSale1函数与getAreaSale2函数的功能一模一样,只不过getAreaSale1函数显得更加有格调一些。 不知道大家有发现没,那些大佬以及源码里所产出的代码里很难看到传统的fori循环,所以本篇博客就是教你如何使用Array中的现有API取代传统的fori循环,从而让自己的代码看起来更像“源码”! 也许这些API的性能不及传统的fori循环高效,但是在绝大多数情况下是相差无几。换句话说,很多时候明明可以使用API简单处理的问题而自己却使用fori循环去实现此API的部分功能来解决问题,此做法就是变相重复造轮子。

正文

以下所有API的讲解我都会结合具体示例并对比传统fori循环进行叙述。 并且为了让大家对于API更有源码的直观感,以下所有的API内部函数的调用我都使用箭头函数的方式。

foreach

foreach可以简单的理解为原始fori的API版本,遍历数组中的每个元素并在回调函数中执行自己的逻辑代码,无返回值。 foreach使用方式:

arr.forEach(callback(currentValue [, index [, array]])[, thisArg])

show you my example:

const arraySparse = [1, 3, 8, 7]; arraySparse.forEach(element => console.log(element)); function foreach(arraySparse) { for (let i = 0; i < arraySparse.length; i++) { console.log(arraySparse[i]); } }

every

every基于遍历所有数组元素的基础上,并判断其所有元素是否都能通过某个指定函数的测试,结果返回一个布尔值。 every的使用方式:

arr.every(callback(element[, index[, array]])[, thisArg])

show you my example:

const arraySparse = [1, 3, 8, 7]; const result = arraySparse.every(element => element <= 8); function every(arraySparse) { for (let i = 0; i < arraySparse.length; i++) { if (arraySparse[i] > 8) { return false; } } return true; }

filter

filter方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素,不改变原数组内容。 filter的使用方式:

const newArray = arr.filter(callback(element[, index[, array]])[, thisArg])

show you my example:

const arraySparse = [1, 3, 8, 7]; const filterArray = arraySparse.filter(element => element > 5); function filter(arraySparse) { const filterArray = []; for (let i = 0; i < arraySparse.length; i++) { if (arraySparse[i] > 5) { filter.push(arraySparse[i]); } } return filterArray; }

find

find方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。 find的使用方式:

arr.find(callback[, thisArg])

show you my example:

const arraySparse = [1, 3, 8, 7]; const findArray = arraySparse.find(element => element > 5); function find(arraySparse) { for (let i = 0; i < arraySparse.length; i++) { if (arraySparse[i] > 5) { return arraySparse[i]; } } return undefined; }

map

map方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值,不改变原数组内容。 map的使用方式:

var new_array = arr.map(function callback(currentValue[, index[, array]]) { // Return element for new_array }[, thisArg])

show you my example:

const arraySparse = [1, 3, 8, 7]; const mapArray = arraySparse.map(element => element + 5); function map(arraySparse) { const mapArray = []; for (let i = 0; i < arraySparse.length; i++) { mapArray.push(arraySparse[i] + 5); } return mapArray; }

some

some方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。 some的使用方式:

arr.some(callback(element[, index[, array]])[, thisArg])

show you my example:

const arraySparse = [1, 3, 8, 7]; const someArray = arraySparse.some(element => element > 8); function some(arraySparse) { for (let i = 0; i < arraySparse.length; i++) { if (arraySparse[i] > 8) { return true; } } return false; }

注:some方法和every方法恰好相反。

reduce

reduce方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。 reduce的使用方式:

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

show you my example:

const arraySparse = [1, 3, 8, 7]; const reduceArray = arraySparse.reduce((acc, cur) => acc + cur, -1); function reduce(arraySparse, index) { let acc = index; for (let i = 0; i < arraySparse.length; i++) { const cur = arraySparse[i]; acc += cur; } return acc; }

小结

上述7种API都有回调函数的功能,其实这个回调函数的代码就是fori循环里的逻辑代码,比如foreach,只不过更多的API相对于fori循环已经帮助我们实现了特定的逻辑代码。看完上述7种API与fori的案例对比,是不是瞬间感觉自己制造了不少重复的轮子。 上述讲述时所给出的案例都是一些最基本的单一应用案例,复杂的案例也不过是换汤不换药,比如文中最开始给的案例,使用foreach+reduce取代fori循环。 最后,熟练掌握这7种API就足矣替代90%及其以上情形的fori循环,至于剩下10%的情形也不是因为无法替代而是使用传统的fori循环效率明显会更高,比如如下的这个案例:

function main() { const values = [ { area: '西安', sale: 123 }, { area: '咸阳', sale: 234 }, { area: '宝鸡', sale: 456 }, { area: '铜川', sale: 567 }, { area: '西安', sale: 345 }, { area: '咸阳', sale: 890 }, { area: '宝鸡', sale: 789 }, { area: '铜川', sale: 678 }, ] const areas = ['西安', '咸阳', '宝鸡', '铜川']; }

稍微更改一下最开始那个案例的数据,只不过这次我想要得到的是如下的结果:

const result = [ [ { area: '西安', sale: 123 }, { area: '西安', sale: 345 } ], [ { area: '咸阳', sale: 234 }, { area: '咸阳', sale: 890 } ], [ { area: '铜川', sale: 567 }, { area: '铜川', sale: 678 } ], [ { area: '宝鸡', sale: 456 }, { area: '宝鸡', sale: 789 } ] ]

此时这种case的数据使用传统的fori循环进行处理效果明显更高,至于原因应该不难想到。

结语

到此,本篇博客的内容就叙述完毕,正文并没有详细的讲解此API的用法,重点在于API与fori循环的使用对比,如果有对API使用有疑惑的朋友,可以参看mdn官方文档进行API学习:Array API使用文档 相信看完本篇博客之后的朋友能够对此类API的使用更加熟练,希望日后每当要使用fori循环时能够第一时间思考到是否可以使用API进行问题处理,从而使自己的代码观感更上一层楼。

最新回复(0)