RxJs groupBy 多條件分組
前言
在Angular或Nest.Js中,使用groupBy分組資料相當方便
但應該是在Nest.Js使用到的機會最多XD
畢竟前端通常都是接到處理完的結果了,只需要渲染頁面就好
作法
比如下列資料,只需以shopId
分組
const array = [
{id: 1, shopId: 'a', category: 'AAA', name: 'Andy', birth: '1990/06/25'},
{id: 2, shopId: 'b', category: 'BBB', name: 'Ben', birth: '1989/01/01'},
{id: 3, shopId: 'a', category: 'AXX', name: 'Amy', birth: '1990/06/01'},
{id: 4, shopId: 'b', category: 'BXX', name: 'Brandon', birth: '1989/05/06'},
{id: 5, shopId: 'a', category: 'AAA', name: 'Anderson', birth: '1991/12/06'},
];
from(array).pipe(
groupBy(val => val.shopId),
mergeMap(group => group.pipe(toArray())
);
// 得到結果如下:
[
[
{id: 1, shopId: 'a', category: 'AAA', name: 'Andy', birth: '1990/06/25'},
{id: 3, shopId: 'a', category: 'AXX', name: 'Amy', birth: '1990/06/01'},
{id: 5, shopId: 'a', category: 'AAA', name: 'Anderson', birth: '1991/12/06'},
],
[
{id: 2, shopId: 'b', category: 'BBB', name: 'Ben', birth: '1989/01/01'},
{id: 4, shopId: 'b', category: 'BXX', name: 'Brandon', birth: '1989/05/06'}
]
]
但若想要多條件,依shopId + category當主鍵來分類
很遺憾不能在groupBy無腦的寫成groupBy(val => {shopId: val.shopId, category: val.category}),
後來在stack overflow(參考資料裡)查到解法
他的寫法摻了不少花括號,猛一看一瞬間還以為要寫的很複雜
但其實就是多一個mergeMap
,裡面再做一次groupBy
就好了!
以上述範例需求:依shopId + category當主鍵來分類
精簡後如下
from(array).pipe(
groupBy(val => val.shopId),
mergeMap(group => group.pipe(toArray()),
mergeMap((_array) =>
from(_array).pipe(
groupBy(val => val.category), // 第2個分組條件
mergeMap(group => group.pipe(toArray())),
)
),
// 後面繼續串接所須的業務邏輯
);
// 得到結果如下:
[
[
{id: 1, shopId: 'a', category: 'AAA', name: 'Andy', birth: '1990/06/25'},
{id: 5, shopId: 'a', category: 'AAA', name: 'Anderson', birth: '1991/12/06'},
],
[
{id: 3, shopId: 'a', category: 'AXX', name: 'Amy', birth: '1990/06/01'},
],
[
{id: 2, shopId: 'b', category: 'BBB', name: 'Ben', birth: '1989/01/01'},
{id: 4, shopId: 'b', category: 'BXX', name: 'Brandon', birth: '1989/05/06'}
]
]
若還有第三、第四個分組條件
依樣畫葫蘆繼續接mergeMap
參考資料
stack overflow / How to groupby by two fields from array using rxjs?