Share utility functions from Timetable

Move the genereic pairs, enumerate and setEquals functions from
Timetable to shared/utils/functions to make them available for reuse.
This commit is contained in:
Hornwitser 2025-03-12 14:44:06 +01:00
parent 29b34deef0
commit f550ca921b
2 changed files with 44 additions and 44 deletions

View file

@ -94,6 +94,7 @@
<script setup lang="ts">
import { DateTime } from "luxon";
import type { Role, ScheduleEvent, ScheduleLocation, Shift, ShiftSlot, TimeSlot } from "~/shared/types/schedule";
import { pairs, setEquals } from "~/shared/utils/functions";
const oneHourMs = 60 * 60 * 1000;
const oneMinMs = 60 * 1000;
@ -128,50 +129,6 @@ type Stretch = {
spans: Span[];
}
/** Returns a tuple consisting of a running index starting from 0, and the item of the iterable */
function* enumerate<T>(iterable: Iterable<T>) {
let index = 0;
for (const item of iterable) {
yield [index++, item] as [number, T];
}
}
/** Returns adjacent pairs from iterable */
function* pairs<T>(iterable: Iterable<T>) {
let first;
let second;
for (const [index, item] of enumerate(iterable)) {
[first, second] = [second, item];
if (index >= 1) {
yield [first, second] as [T, T];
}
}
}
/**
Returns true if all sets are equal
@param sets set to compare
@returns true if all sets are the same size and have the same elements
*/
function setEquals<T>(...sets: Set<T>[]) {
if (sets.length < 2) {
throw TypeError("At least two sets must be passed to setEquals");
}
const ref = sets[0];
const rest = sets.slice(1);
if (rest.some(set => set.size !== ref.size)) {
return false;
}
for (const set of rest) {
for (const el of set) {
if (!ref.has(el)) {
return false;
}
}
}
return true;
}
function* edgesFromEvents(events: Iterable<ScheduleEvent>): Generator<Edge> {
for (const event of events) {
for (const slot of event.slots) {

43
shared/utils/functions.ts Normal file
View file

@ -0,0 +1,43 @@
/** Returns a tuple consisting of a running index starting from 0, and the item of the iterable */
export function* enumerate<T>(iterable: Iterable<T>) {
let index = 0;
for (const item of iterable) {
yield [index++, item] as [number, T];
}
}
/** Returns adjacent pairs from iterable */
export function* pairs<T>(iterable: Iterable<T>) {
let first;
let second;
for (const [index, item] of enumerate(iterable)) {
[first, second] = [second, item];
if (index >= 1) {
yield [first, second] as [T, T];
}
}
}
/**
Returns true if all sets are equal
@param sets set to compare
@returns true if all sets are the same size and have the same elements
*/
export function setEquals<T>(...sets: Set<T>[]) {
if (sets.length < 2) {
throw TypeError("At least two sets must be passed to setEquals");
}
const ref = sets[0];
const rest = sets.slice(1);
if (rest.some(set => set.size !== ref.size)) {
return false;
}
for (const set of rest) {
for (const el of set) {
if (!ref.has(el)) {
return false;
}
}
}
return true;
}