JavaScript中常用數(shù)據(jù)處理函數(shù)groupBy的用法詳解
一、前言
數(shù)據(jù)處理與分析中,對數(shù)據(jù)進(jìn)行分組是非常常見的功能,不論是實(shí)際工作中,還是在面試的場景中應(yīng)用十分廣泛。尤其在函數(shù)式編程中 groupBy 十分常見。在 JavaScript 中 groupBy 也已經(jīng)進(jìn)入了 JS 的標(biāo)準(zhǔn)。
二、介紹
groupBy 函數(shù)是一個(gè)用于對 數(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ù)是可迭代對象,第二參數(shù)是回調(diào)函數(shù)
Map.groupBy
Map.groupBy(items, callbackFn) // 語法,第一個(gè)參數(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') // ? 第二個(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)行 累加。從 {} 對象開始,然后再對象上賦值對應(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ì)也非常簡單就是 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)可觀察對象。后面的邏輯也是實(shí)用 reduce 進(jìn)行累加計(jì)算。然后對外輸出數(shù)據(jù)
十、groupBy 其他
- 在 SQL 中,GROUP BY 語句用于將行分組為匯總行。
- 在 Python 中,可以使用
itertools.groupby對可迭代對象進(jìn)行分組。 - 在一些數(shù)據(jù)處理例如 excel 以及 python 的工具庫中。
十一、小結(jié)
本文主要介紹 JavaScript 中的 groupBy 函數(shù)實(shí)用特性。從 ES 標(biāo)準(zhǔn)草案,到自己實(shí)現(xiàn)一個(gè)簡單的 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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js實(shí)現(xiàn)Element中input組件的部分功能并封裝成組件(實(shí)例代碼)
這篇文章主要介紹了純生js實(shí)現(xiàn)Element中input組件的部分功能(慢慢完善)并封裝成組件,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
JavaScript中的call和apply的用途以及區(qū)別
本文主要介紹了JavaScript中的call和apply的用途以及區(qū)別。具有很好的參考價(jià)值,下面跟著小編一起來看下吧2017-01-01
JavaScript實(shí)現(xiàn)金額格式化(元轉(zhuǎn)成萬元)的示例代碼
這篇文章主要為大家詳細(xì)介紹了在JavaScript中將金額轉(zhuǎn)換為萬元單位的幾種方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2026-04-04
javascript動態(tài)設(shè)置樣式style實(shí)例分析
這篇文章主要介紹了javascript動態(tài)設(shè)置樣式style的方法,實(shí)例分析了javascript操作style樣式的易錯(cuò)點(diǎn)和相關(guān)使用技巧,需要的朋友可以參考下2015-05-05

