如何使用GroupBy管道按指定日期格式('YYYY-MM-DD')分组数据
Got it, let's get this grouping sorted so you can group your players by just the date portion (like 2019-09-18) instead of the full timestamp string. Here are two practical approaches you can use:
Approach 1: Modify the Existing Pipe for Date-Specific Handling
If you only need this grouping behavior for the date field, you can tweak your existing GroupByPipe to automatically split the date string when grouping by date.
Updated Pipe Code
@Pipe({name: 'groupBy'}) export class GroupByPipe implements PipeTransform { transform(collection: Array<any>, property: string): Array<any> { if(!collection) { return null; } const groupedCollection = collection.reduce((previous, current)=> { // Extract the date part if the property is 'date' const keyValue = property === 'date' && current[property] ? current[property].split('T')[0] : current[property]; if(!previous[keyValue]) { previous[keyValue] = [current]; } else { previous[keyValue].push(current); } return previous; }, {}); return Object.keys(groupedCollection).map(key => ({ key, value: groupedCollection[key] })); } }
HTML Usage (No Changes Needed!)
Your existing HTML will work exactly as before—no updates required:
<ul> <div *ngFor="let playerGroup of players | groupBy:'date'"> Date : {{playerGroup.key}} <li *ngFor="let eachplayer of playerGroup.value"> {{eachplayer.name}} </li> </div> </ul>
Approach 2: Make the Pipe Universal with Custom Key Generators
If you want a more flexible pipe that can handle any grouping logic (not just dates), extend it to accept a custom function that generates the group key. This is great for future-proofing your code.
Updated Pipe Code
@Pipe({name: 'groupBy'}) export class GroupByPipe implements PipeTransform { // Overload to support both property name and custom function inputs transform(collection: Array<any>, keyFn: (item: any) => string): Array<any>; transform(collection: Array<any>, property: string): Array<any>; transform(collection: Array<any>, keyOrFn: string | ((item: any) => string)): Array<any> { if(!collection) { return null; } const groupedCollection = collection.reduce((previous, current)=> { // Determine the group key based on input type const keyValue = typeof keyOrFn === 'function' ? keyOrFn(current) : current[keyOrFn]; if(!previous[keyValue]) { previous[keyValue] = [current]; } else { previous[keyValue].push(current); } return previous; }, {}); return Object.keys(groupedCollection).map(key => ({ key, value: groupedCollection[key] })); } }
Component Setup
Add a method to your component class that generates the date-based key:
// Inside your component class getDateGroupKey(player: any): string { // Safely handle invalid date strings (add error handling if needed) return player.date?.split('T')[0] || 'Invalid Date'; }
HTML Usage
Now pass the custom function to the pipe:
<ul> <div *ngFor="let playerGroup of players | groupBy:getDateGroupKey"> Date : {{playerGroup.key}} <li *ngFor="let eachplayer of playerGroup.value"> {{eachplayer.name}} </li> </div> </ul>
Quick Note
Heads up: Your sample dataset has invalid date strings like
2019-20-18T12:45:42(month can't be 20). You'll want to fix those first to avoid unexpected behavior in your grouping!
内容的提问来源于stack exchange,提问作者Greg-A

