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