[feat-216] refactored sorting services to classes and const

This commit is contained in:
silentrald
2025-01-10 01:02:39 +08:00
parent 1d70c867f3
commit e89333ea09
5 changed files with 95 additions and 110 deletions
+42
View File
@@ -0,0 +1,42 @@
import { Comparison } from "../comparator.type";
import { Sorter } from "../sorter.model";
import { BsmLocalMap } from "./bsm-local-map.interface";
const sortName = (map1: BsmLocalMap, map2: BsmLocalMap) => map1.mapInfo.songName.localeCompare(map2.mapInfo.songName);
export const mapSorter = new Sorter<BsmLocalMap>({
comparators: {
name: sortName,
"song-author": (map1, map2) => map1.mapInfo.songAuthorName.localeCompare(map2.mapInfo.songAuthorName),
"map-author": (map1, map2) => {
// Compare the number of mappers, else compare the first mapper
const difference = map1.mapInfo.levelMappers.length - map2.mapInfo.levelMappers.length;
return difference || map1.mapInfo.levelMappers[0].localeCompare(map2.mapInfo.levelMappers[0]);
},
bpm: (map1, map2) => map1.mapInfo.beatsPerMinute - map2.mapInfo.beatsPerMinute,
duration: (map1, map2) => {
if (!map1.songDetails) {
return map2.songDetails ? Comparison.LESSER : Comparison.EQUAL;
}
return !map2.songDetails ? Comparison.GREATER : map1.songDetails.duration - map2.songDetails.duration;
},
likes: (map1, map2) => {
if (!map1.songDetails) {
return map2.songDetails ? Comparison.LESSER : Comparison.EQUAL;
}
return !map2.songDetails ? Comparison.GREATER : map1.songDetails.upVotes - map2.songDetails.upVotes;
},
"date-uploaded": (map1, map2) => {
if (!map1.songDetails) {
return map2.songDetails ? Comparison.LESSER : Comparison.EQUAL;
}
return !map2.songDetails ? Comparison.GREATER : map1.songDetails.uploadedAt - map2.songDetails.uploadedAt;
},
},
tiebreak: sortName,
defaultKey: "name"
});
+30
View File
@@ -0,0 +1,30 @@
import { Comparison } from "../comparator.type";
import { Sorter } from "../sorter.model";
import { LocalBPListsDetails } from "./local-playlist.models";
const sortTitle = (playlist1: LocalBPListsDetails, playlist2: LocalBPListsDetails) =>
playlist1.playlistTitle.localeCompare(playlist2.playlistTitle);
export const playlistSorter = new Sorter({
comparators: {
title: sortTitle,
author: (playlist1, playlist2) => playlist1.playlistAuthor.localeCompare(playlist2.playlistAuthor),
"number-of-maps": (playlist1, playlist2) => playlist1.nbMaps - playlist2.nbMaps,
duration: (playlist1, playlist2) => {
if (!playlist1.duration) {
return playlist2.duration ? Comparison.LESSER : Comparison.EQUAL;
}
return !playlist2.duration ? Comparison.GREATER : playlist1.duration - playlist2.duration;
},
"notes-per-second": (playlist1, playlist2) => {
if (!playlist1.maxNps) {
return playlist2.maxNps ? Comparison.LESSER : Comparison.EQUAL;
}
return !playlist2.maxNps ? Comparison.GREATER : playlist1.maxNps - playlist2.maxNps;
},
},
tiebreak: sortTitle,
defaultKey: "title",
});
+36
View File
@@ -0,0 +1,36 @@
import { Comparator } from "./comparator.type";
export type SorterOptions<T> = {
defaultKey: string;
comparators: Record<string, Comparator<T>>;
tiebreak: Comparator<T>;
}
export class Sorter<T> {
public readonly defaultKey: string;
private readonly comparators: Record<string, Comparator<T>>;
private readonly tiebreak: Comparator<T>;
constructor(options: SorterOptions<T>) {
this.defaultKey = options.defaultKey;
this.comparators = options.comparators;
this.tiebreak = options.tiebreak;
}
public getComparatorKeys(): string[] {
return Object.keys(this.comparators);
}
public getDefaultComparator(): Comparator<T> {
return this.comparators[this.defaultKey];
}
public getComparator(key: string): Comparator<T> {
const comparator = this.comparators[key] || this.comparators[this.defaultKey];
return this.tiebreak === comparator
? comparator
: (object1, object2) => comparator(object1, object2) || this.tiebreak(object1, object2);
}
}