JavaScript中常用數(shù)據(jù)處理函數(shù)groupBy的用法詳解
一、前言
數(shù)據(jù)處理與分析中,對(duì)數(shù)據(jù)進(jìn)行分組是非常常見的功能,不論是實(shí)際工作中,還是在面試的場(chǎng)景中應(yīng)用十分廣泛。尤其在函數(shù)式編程中 groupBy 十分常見。在 JavaScript 中 groupBy 也已經(jīng)進(jìn)入了 JS 的標(biāo)準(zhǔn)。
二、介紹
groupBy
函數(shù)是一個(gè)用于對(duì) 數(shù)組元素
進(jìn)行 分組
的實(shí)用函數(shù)。groupBy
允許我們指定分組條件,將數(shù)組的元素分為不同的組,用于數(shù)據(jù)處理或者展示。
三、標(biāo)準(zhǔn)
proposal-array-grouping: tc39.es/proposal-array-grouping/#sec-scope
Object.groupBy
Object.groupBy(items, callbackFn) // 語法,第一個(gè)參數(shù)是可迭代對(duì)象,第二參數(shù)是回調(diào)函數(shù)
Map.groupBy
Map.groupBy(items, callbackFn) // 語法,第一個(gè)參數(shù)是可迭代對(duì)象,第二參數(shù)是回調(diào)函數(shù)
四、環(huán)境支持
五、Object.groupBy 示例
const data = [ { id: 1, type: 'A' }, { id: 2, type: 'B' }, { id: 3, type: 'A' }, { id: 4, type: 'C' }, { id: 5, type: 'B' }, ]; const groupType = Object.groupBy(data, 'type') // ? 第二個(gè)參數(shù)必須是函數(shù) const groupType = Object.groupBy(data, (item) => item.type) // ? 按照類型進(jìn)行分類, 并且 type 就是 group 的 key 值。 // { // A: [{…}, {…}] // B: [{…}, {…}] // C: [{…}] / }
六、實(shí)現(xiàn)一個(gè)按照給 key 據(jù)分組
雖然函數(shù)通用性更加廣泛,但是復(fù)雜度比直接傳遞數(shù)據(jù)要稍微高一點(diǎn),這里實(shí)現(xiàn)一個(gè)按照傳遞屬性方式實(shí)現(xiàn)一個(gè) groupBy:
function groupBy(arr, key) { return arr.reduce((acc, obj) => { const groupKey = obj[key]; acc[groupKey] = acc[groupKey] || []; acc[groupKey].push(obj); return acc; }, {}); } // data 復(fù)用以上的 data groupBy(data, 'type') // 輸出結(jié)果與 Object.groupBy 一致
實(shí)現(xiàn)的核心思想就是 reduce
進(jìn)行 累加
。從 {}
對(duì)象開始,然后再對(duì)象上賦值對(duì)應(yīng)key為空數(shù)組,符合這個(gè)key 的就進(jìn)入此分組。
七、實(shí)現(xiàn)一個(gè)通用的 groupBy
有了基于 key 實(shí)現(xiàn) groupBy 之后,實(shí)現(xiàn)通用的 groupBy 就比較容易了:
type KeyFunc<T> = (obj: T) => string export function groupByWithFn<T>( array: T[], keyFunc: KeyFunc<T> ): Record<string, T[]> { return array.reduce((acc: Record<string, T[]>, obj: T) => { const key: string = keyFunc(obj) if (!acc[key]) { acc[key] = [] } acc[key].push(obj) return acc }, {}) }
這里用 TS 實(shí)現(xiàn)主要約束類型,本質(zhì)也非常簡(jiǎn)單就是 keyFunc
用當(dāng)前的 obj
執(zhí)行獲取 key,如果沒有獲取到了,設(shè)置一個(gè)空的數(shù)組初始化,并將數(shù)據(jù)填充進(jìn)去。重復(fù)累積這個(gè)過程。
八、lodash z中的 groupBy
_.groupBy(data, (item) => item.type)
lodash 將 groupBy 放在 collection 集合中,而非數(shù)組中。實(shí)用方式與以上基本一致。
九、rxjs groupBy
如果是函數(shù)式編程,當(dāng)然離不開 RxJS 中數(shù)據(jù)操作。rxjs groupBy 不能單獨(dú)的實(shí)現(xiàn) js 中 groupBy 的功能,當(dāng)然我們組合操作符或者自定義操作符實(shí)現(xiàn)。以下是實(shí)現(xiàn)一個(gè)自定義操作符 customGroupBy
:
import { Observable, of } from 'rxjs'; import { map, mergeMap, reduce } from 'rxjs/operators'; // 自定義 groupBy 操作符 function customGroupBy(keySelector) { return function (source) { return new Observable((observer) => { source.pipe( mergeMap((arr) => arr), reduce((acc, val) => { const key = keySelector(val); acc[key] = acc[key] || []; acc[key].push(val); return acc; }, {}) ).subscribe({ next: (result) => { observer.next(result); observer.complete(); }, error: (err) => observer.error(err), }); }); }; } of([ { id: 1, type: 'A' }, { id: 2, type: 'B' }, { id: 3, type: 'A' }, { id: 4, type: 'C' }, { id: 5, type: 'B' }, ]).pipe( customGroupBy((obj) => obj.type) ).subscribe({ next: (v) => {console.log(v)} });
customGroupBy 操作符,接受一個(gè)函數(shù)作為參數(shù),當(dāng)然這個(gè)函數(shù)式是一個(gè)閉包,包含了 of 操作符中的靜態(tài)數(shù)據(jù)。customGroupBy 是典型的自定義操作符實(shí)現(xiàn),source 的就是 of 制作的靜態(tài)可觀察對(duì)象。后面的邏輯也是實(shí)用 reduce 進(jìn)行累加計(jì)算。然后對(duì)外輸出數(shù)據(jù)
十、groupBy 其他
- 在 SQL 中,GROUP BY 語句用于將行分組為匯總行。
- 在 Python 中,可以使用
itertools.groupby
對(duì)可迭代對(duì)象進(jìn)行分組。 - 在一些數(shù)據(jù)處理例如 excel 以及 python 的工具庫中。
十一、小結(jié)
本文主要介紹 JavaScript 中的 groupBy 函數(shù)實(shí)用特性。從 ES 標(biāo)準(zhǔn)草案,到自己實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 groupBy, 再到 lodash 以及 RxJS 中實(shí)現(xiàn) groupBy 效果。在函數(shù)式編程中,groupBy 實(shí)用特性非常高,在數(shù)據(jù)處理領(lǐng)域廣泛適用。
到此這篇關(guān)于JavaScript中常用數(shù)據(jù)處理函數(shù)groupBy的用法詳解的文章就介紹到這了,更多相關(guān)JavaScript groupBy內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于jquery實(shí)現(xiàn)的省市區(qū)級(jí)聯(lián)無ajax
省市區(qū)級(jí)聯(lián)的實(shí)現(xiàn)方法有很多,在本文為大家介紹下如何使用jquery無ajax來實(shí)現(xiàn),感興趣的朋友可以參考下,希望對(duì)大家有所幫助2013-09-09Pixi.js實(shí)現(xiàn)可視化圖形編輯器的方法
本文主要介紹了Pixi.js實(shí)現(xiàn)可視化圖形編輯器的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03JavaScript數(shù)組扁平轉(zhuǎn)樹形結(jié)構(gòu)數(shù)據(jù)(Tree)的實(shí)現(xiàn)
本文主要介紹了JavaScript數(shù)組扁平轉(zhuǎn)樹形結(jié)構(gòu)數(shù)據(jù)(Tree)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08html向js方法傳遞參數(shù)具體實(shí)現(xiàn)
html如何向js方法傳遞參數(shù),在本文將為大家詳細(xì)介紹下html注冊(cè)事件向引用方法中的傳參問題,感興趣的朋友可以參考下,希望對(duì)大家有所幫助2013-08-08js核心基礎(chǔ)之構(gòu)造函數(shù)constructor用法實(shí)例分析
這篇文章主要介紹了js核心基礎(chǔ)之構(gòu)造函數(shù)constructor用法,結(jié)合具體實(shí)例形式分析了javascript構(gòu)造函數(shù)constructor概念、原理、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2019-05-05用js實(shí)現(xiàn)的自定義的對(duì)話框的實(shí)現(xiàn)代碼
javascript alert函數(shù)的替代方案,一個(gè)自定義的對(duì)話框的方法2010-03-03javascript獲取和判斷瀏覽器窗口、屏幕、網(wǎng)頁的高度、寬度等
這篇文章主要介紹了javascript獲取和判斷瀏覽器窗口、屏幕、網(wǎng)頁的高度、寬度等,需要的朋友可以參考下2014-05-05js改變img標(biāo)簽的src屬性在IE下沒反應(yīng)的解決方法
在Chrome FF里都能改變成功,但在IE下卻不行,網(wǎng)上搜了半天,大概了解了,這個(gè)是IE的一個(gè)bug,具體的解決方法如下,有類似問題的朋友可以參考下哈,希望對(duì)大家有所幫助2013-07-07中國(guó)地區(qū)三級(jí)聯(lián)動(dòng)下拉菜單效果分析
主要的數(shù)據(jù)和功能實(shí)現(xiàn)都是在js文件中,網(wǎng)上找的地區(qū)數(shù)據(jù)有的地方不完整,需要自己添加,本文將詳細(xì)介紹2012-11-11