chore: use fisheryates for array shuffle

This commit is contained in:
2025-05-31 17:58:52 +02:00
parent 3c9ddd466d
commit de176acd8f
4 changed files with 19 additions and 4 deletions

13
src/lib/fisheryates.ts Normal file
View File

@@ -0,0 +1,13 @@
// source: https://decipher.dev/30-seconds-of-typescript/docs/shuffle/
// modified to use existing SIMDMersenneTwister constructor for random number generation
import type { SIMDMersenneTwister } from "./mersenne";
export const fisherYates = (sfml: SIMDMersenneTwister, ...arr: any[]) => {
let m = arr.length;
while (m) {
const i = Math.floor(sfml.random() * m--);
[arr[m], arr[i]] = [arr[i], arr[m]];
}
return arr;
};

View File

@@ -14,7 +14,7 @@ export const state = $state({
isLoading: true,
error: null as string | null,
currentTime: 0,
duration: 0 as number | undefined,
duration: 0,
presets: [] as Preset[],
stations: [] as Station[],

View File

@@ -1,5 +1,6 @@
import type { Song } from "@/types";
import { SIMDMersenneTwister } from "@/mersenne";
import { fisherYates } from "@/fisheryates";
export async function getSleepStationSongs(): Promise<Song[]> {
const m = new SIMDMersenneTwister();
@@ -16,9 +17,10 @@ export async function getSleepStationSongs(): Promise<Song[]> {
title: title,
image: `https://lofi-cdn.srizan.dev/sleep/thumbs/${file.replace('.opus', '')}.webp`,
label: 'Chilled Cat',
duration: 0, // TODO: get duration for all songs and put them in list.json
};
}) as Song[];
const shuffled = mapped.sort(() => 0.5 - m.random()).slice(0, 5);
const shuffled = fisherYates(m, mapped).slice(0, 5);
return shuffled;
}

View File

@@ -3,9 +3,9 @@ export interface Song {
title: string;
endpoint: string;
image: string;
duration: number; // not really used right now
label?: string; // optional record label
spotifyId?: string; // TODO: enforce in the future for all spotify scraped stations
duration?: number; // TODO: enforce in all stations
spotifyId?: string; // TODO: enforce in the future for all spotify scraped stations, unused atm.
}
export interface CHSong {