最近收到一個(gè)需求:
開(kāi)發(fā)了一個(gè)報(bào)名功能,因?yàn)橐恍┨厥庠?,用?hù)可以重復(fù)報(bào)名,但是要在前端標(biāo)記出來(lái)哪些用戶(hù)是重復(fù)報(bào)名的。
比如
orderList=
[
{userName:"黃大錘",desc:"灑家想要個(gè)冰箱"},
{userName:"李桂芬",desc:"俺想要條圍巾"},
{userName:"黃大錘",desc:"灑家還想要個(gè)冰柜"},
......n條數(shù)據(jù)......
{userName:"張家寶",desc:"偶家里需要一臺(tái)電視機(jī)"}
]
這里黃大錘就是重復(fù)報(bào)名,需要標(biāo)記出來(lái)。
第一時(shí)間就想到groupBy好像能解決這個(gè)問(wèn)題。
----------第一個(gè)錯(cuò)誤版本 開(kāi)始----------
這個(gè)是錯(cuò)誤版本,記錄下來(lái)完全是為了避免自己以后再次踩這個(gè)坑。
不過(guò)對(duì)代碼改進(jìn)過(guò)程不感興趣的可以跳到 【第一個(gè)錯(cuò)誤版本 結(jié)束】的位置。
這里的錯(cuò)誤還是對(duì)RxJS理解不深刻導(dǎo)致的。
兩層subscribe嵌套,并不是想兩個(gè)for循環(huán)嵌套一樣,按照一條一條的順序執(zhí)行的。
這里的是并行處理的。所以count的統(tǒng)計(jì)和first 的指向都是錯(cuò)誤的。
最開(kāi)始的時(shí)候只有一條重復(fù)的數(shù)據(jù),所以測(cè)試并沒(méi)有暴露出這個(gè)問(wèn)題。
后面后多條重復(fù)記錄后,就會(huì)出現(xiàn)混亂了。
let first : any;
from<any>(orderList).pipe(groupBy(order=>order.userName)).subscribe(obs=>{
let count = 0;
obs.subscribe(order=>{
count++;
if(count==1){
first = order;//如果有重復(fù)的話(huà),需要回頭把第一條標(biāo)記出來(lái),所以這里要記錄一下
}else if(count>1){
first.isRepeat = true;//標(biāo)記first為重復(fù)項(xiàng)
order.isRepeat = true;//標(biāo)記order為重復(fù)項(xiàng)
}
})
})
----------第一個(gè)錯(cuò)誤版本 結(jié)束----------
不用引入其他變量,我們用reduce將一個(gè)observer的拋出值全部丟進(jìn)一個(gè)數(shù)組里。
然后根據(jù)數(shù)組的長(zhǎng)度來(lái)判斷是否重復(fù)了。
from<any>(orderList).pipe(groupBy(order=>order.userName)).subscribe(obs=>{
obs.pipe(reduce(x,y)=>[...x,y],[]).subscribe(orders=>{
if(orders.length>1){
orders.forEach(order=>{
order.isRepeat = true;
})
}
})
})
最后的結(jié)果是:
orderList=
[
{userName:"黃大錘",desc:"灑家想要個(gè)冰箱",isRepeat :true},
{userName:"李桂芬",desc:"俺想要條圍巾"},
{userName:"黃大錘",desc:"灑家還想要個(gè)冰柜",isRepeat :true},
......n條數(shù)據(jù)......
{userName:"張家寶",desc:"偶家里需要一臺(tái)電視機(jī)"}
]
總覺(jué)得中間的部分可以有更好的辦法去簡(jiǎn)化邏輯,不過(guò)RxJS用的比較少,暫時(shí)沒(méi)想出來(lái)。
希望有高手出來(lái)指教一二。先謝過(guò)。