成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

深入淺出數組reduce,看完就會

開發 前端
如果reduce?給了初始值,那么prev?是就是當前傳入的初始值,如果沒有初始值,則默認就是當前數組的首項,cur就是第二元素,默認沒有初始值會比給初始值少一次循環。

本篇是筆者深入理解reduce的一篇筆記,希望看完在項目中有所思考和幫助。

reduce

reduce() 方法對數組中的每個元素按序執行一個由您提供的 reducer 函數,每一次運行 reducer 會將先前元素的計算結果作為參數傳入,最后將其結果匯總為單個返回值。,這是官方MDN上給的一段話。

每次將會把前一次的計算結果當成下次的參數傳入,什么意思?

我們看一下簡單的例子;

const sum = (arr) => {
return arr.reduce((prev, cur) => {
return prev + cur
}, 0)
}
console.log('sum: ', sum([1,2,3,4,5])) // 15

結果是15,嘿,這個sum就是這么簡單嗎?我們看下之前是怎么寫的;

const sum2 = (arr) => {
let ret = 0;
arr.forEach(val => {
ret+=val;
})
return ret
}
console.log('sum2:', sum2([1,2,3,4,5])) // 15

我們發現在之前我們的做法是循環計算,reduce的方式比循環方式代碼要簡單得多,但是并不是像循環方式一樣那么通俗易懂,具體我們斷點分析一下;

const sum = (arr) => {
return arr.reduce((prev, cur) => {
debugger;
return prev + cur
}, 0)
}
console.log('sum: ', sum([1,2,3,4,5])) // 15

首次:

圖片

其實我們發現,?reduce?回調函數內,第一個參數prev?默認就是初始值傳入的0?,然后cur就是每次循環數組的當前值。

第一次:prev:0, cur: 1,執行返回結果0+1,為第二次循環的初始值prev:1。

第二次:prev:1, cur:2,執行返回結果1+2,為第三次循環的初始值prev:3。

...

第五次:prev:10, cur:5,執行返回結果10+5,結束。

所以我們始終記住這個萬能公式就行,prev首次是默認傳入的值,當循環迭代下一次循環時,會將上一次返回的結果作為prev,cur永遠是當前迭代的item。

var arr = [];
const callback = (prev, current, currentIndex, source) => {
// 首次prev = init, 后面每次計算后結果作為下一次的prev,current是當前arr的item
// current: 當前的數組的item
// currentIndex: 當前索引
// source 原數組,也是arr
}
arr.reduce(callback, init?)

注意init是可選的,如果有值,則prev默認取它,那么current就取默認第一個值,如果init沒有值,那么prev就是第一個,current就是第二值,你會發現不給默認值,比給默認值少了一次循環。

const sum = (arr) => {
return arr.reduce((prev, cur, curentIndex, arr) => {
console.log(prev, cur, curentIndex, arr)
return prev + cur
})
}
console.log('sum: ',sum([1,2,3,4,5])) // 15
// 1 2 1 [1, 2, 3, 4, 5]
// 3 3 2 [1, 2, 3, 4, 5]
// 6 4 3 [1, 2, 3, 4, 5]
// 10 5 4 [1, 2, 3, 4, 5]

過濾數據中指定字段數據;

用reduce過濾指定需要的字段;

let sourceArr = [
{id: 1, name: 'Web技術學苑', age: 18},
{id: 2, name: 'Maic', age: 20},
{id: 3, name: 'Tom', age: 16},
]
const ret = sourceArr.reduce((prev, cur) => {
const {id, age} = cur;
return prev.concat({id, age})
}, [])
console.log(ret);
// [ { id: 1, age: 18 }, { id: 2, age: 20 }, { id: 3, age: 16 } ]

如果是用map大概就是下面這樣的了。

...
const ret2 = sourceArr.map(v => {
return { id: v.id, age: v.age }
})
console.log('ret2', ret2);

多維數組打平,二維轉一維;

reduce是下面這樣的;

const sourceArr2 = [[1,2,3], [4,5,6], [8,9], 0]
const ret3 = sourceArr2.reduce((prev, cur) => {
return prev.concat(cur)
}, [])

以前你可能會這樣的;

...
const ret4 = sourceArr2.flat(1)

或者用遞歸方式;

var flatLoop = (source, ret = []) => {
const loop = (arr) => {
arr.forEach(v => {
if (Array.isArray(v)) {
loop(v)
} else {
ret.push(v)
}
})
}
loop(source)
return ret
}
flatLoop(sourceArr2, [])

統計一個字符出現的次數;

forEach版本;

const strCount = (arr) => {
const obj = {}
arr.forEach(key => {
if (key in obj) {
obj[key]+=1;
} else {
obj[key]=1;
}
});
return obj
}
const ret5 = strCount(['a', 'a', 'b', 'c', 'd'])
console.log('ret5', ret5)
// ret5 {a: 2, b: 1, c: 1, d: 1}

reduce版本實現;

const strCount2 = (arr) => {
return arr.reduce((prev, cur) => {
if (cur in prev) {
prev[cur]+=1;
} else {
prev[cur] = 1;
}
return prev
}, {})
}
console.log('ret6', strCount2(['a', 'a', 'b', 'c', 'd']))

獲取數組中某個字段的所有集合;

var publicInfo = [
{
id: '1',
name: 'Web技術學苑',
age: 8
},
{
id: '2',
name: '前端從進階到入院',
age: 10
},
{
id: '3',
name: '前端之神',
age: 15
},
{
id: '3',
name: '前端之巔',
age: 12
}
]
const ret7 = publicInfo.map(v => v.name)
console.log('ret7', ret7)

reduce實現;

const ret8 = publicInfo.reduce((prev, cur) => {
return prev.concat(cur.name)
}, [])
console.log('ret8', ret8)

數據去重;

以前你可以用Set或者循環去做的

const sourceData = ['1','1', '2', 3,4,5,3]
console.log([...new Set(sourceData)]) // ['1','2',3,4,5]
// or
const obj = {}
sourceData.forEach(item => {
obj[item] = item
})
console.log(Object.values(obj))

reduce實現去重。

...
consy ret9 = sourceData.reduce((prev, cur) => {
if (prev.indexOf(cur) === -1) {
prev.push(cur)
}
return prev
}, [])

代替filter與map

假設我們有一個場景,就是在原數據中過濾找出age>10大于的數據并返回對應的name。

var publicInfo = [
{
id: '1',
name: 'Web技術學苑',
age: 10
},
{
id: '2',
name: '前端從進階到入院',
age: 10
},
{
id: '3',
name: '前端之神',
age: 12
},
{
id: '3',
name: '前端之巔',
age: 12
}
]
const ret11 = publicInfo.filter(v => v.age >10).map(v => v.name);
console.log(ret11); // ['前端之神', '前端之巔']

我們知道上面使用filter與map有兩次循環,但是reduce就可以做到僅一次循環就可以搞定。

...
publicInfo.reduce((prev, cur) => {
if (cur.age > 10) {
prev.push(cur.name)
}
return prev
}, [])

關于reduce[1]更多的實踐可以參考MDN文檔,在項目中更多的實踐以后再一一補充。

總結

主要分析了reduce這個計算方法特性,每次計算的結果會當成下一次的prev的初始值,第二個參數``cur`是當前循環數組的值。

如果reduce給了初始值,那么prev是就是當前傳入的初始值,如果沒有初始值,則默認就是當前數組的首項,cur就是第二元素,默認沒有初始值會比給初始值少一次循環。

以reduce實踐了一些例子,夯實reduce的一些用法特性。

本文示例源碼code example[2]。

參考資料

[1]reduce: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

[2]code example: https://github.com/maicFir/lessonNote/tree/master/javascript/22-reduce

責任編輯:武曉燕 來源: Web技術學苑
相關推薦

2022-09-26 09:01:15

語言數據JavaScript

2011-07-04 10:39:57

Web

2021-03-16 08:54:35

AQSAbstractQueJava

2019-01-07 15:29:07

HadoopYarn架構調度器

2021-07-20 15:20:02

FlatBuffers阿里云Java

2012-05-21 10:06:26

FrameworkCocoa

2017-07-02 18:04:53

塊加密算法AES算法

2009-11-17 17:31:58

Oracle COMM

2016-10-14 13:53:05

JavascriptDOMWeb

2010-07-16 09:11:40

JavaScript內存泄漏

2016-10-14 14:32:58

JavascriptDOMWeb

2010-07-26 12:57:12

OPhone游戲開發

2023-12-04 13:22:00

JavaScript異步編程

2021-07-19 11:54:15

MySQL優先隊列

2024-01-09 12:05:24

SSH協議端口

2022-01-11 07:52:22

CSS 技巧代碼重構

2025-03-27 09:38:35

2021-04-27 08:54:43

ConcurrentH數據結構JDK8

2019-11-11 14:51:19

Java數據結構Properties

2022-12-02 09:13:28

SeataAT模式
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩精品免费 | 欧美精品被| 日韩高清三区 | 成人免费在线视频 | 国产精品免费观看 | 视频一区二区三区四区五区 | 偷拍自拍在线观看 | 日韩欧美三区 | 国产精品久久久久久久久久三级 | 污片在线观看 | 久久亚洲免费 | 懂色av一区二区三区在线播放 | 一区二区三区在线电影 | av色站 | 美日韩中文字幕 | 午夜电影网 | 视频第一区| 一区二区三区欧美 | 97日日碰人人模人人澡分享吧 | 亚洲欧美一区二区三区国产精品 | 亚洲一区二区三区在线免费观看 | 欧美日韩精品一区二区天天拍 | 91在线视频播放 | 亚洲视频一区在线播放 | 成人视屏在线观看 | 久久黄视频 | 午夜精品久久久久久久星辰影院 | 欧美一级二级三级视频 | 久久久噜噜噜www成人网 | 欧美一区二区三区四区五区无卡码 | 嫩草视频在线免费观看 | 亚洲三区在线观看 | 日韩成人| 一区二区三区四区在线 | 久久成人精品一区二区三区 | 精产国产伦理一二三区 | 久久国产精品99久久久大便 | 亚洲国产一区二区三区在线观看 | 久久机热 | 久草综合在线视频 | 精品视频免费 |