Lab
Strategy
type SearchResult = {
id: string;
score: number;
ageDays: number;
deprecated: boolean;
};
// A policy compares two results. Negative: a first. Zero: tied. Positive: b first.
type RankingPolicy = (a: SearchResult, b: SearchResult) => number;
// Deprecated pages sink below current ones; then the highest score first.
function byRelevance(a: SearchResult, b: SearchResult): number {
if (a.deprecated !== b.deprecated) return a.deprecated ? 1 : -1;
return b.score - a.score;
}
function byRecent(a: SearchResult, b: SearchResult): number {
return a.ageDays - b.ageDays;
}
// The caller's choice, by name.
function choosePolicy(name: string): RankingPolicy {
switch (name) {
case 'relevance':
return byRelevance;
case 'recent':
return byRecent;
default:
throw new Error(`unknown ranking policy: ${name}`);
}
}
// The shared workflow: copy, ask the policy, and settle its ties by ID.
function rankResults(items: SearchResult[], policy: RankingPolicy): SearchResult[] {
const ranked = [...items];
function compare(a: SearchResult, b: SearchResult): number {
const order = policy(a, b);
const tied = order === 0;
if (!tied) return order;
return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
}
ranked.sort(compare);
return ranked;
}