35 lines
1.0 KiB
JavaScript
35 lines
1.0 KiB
JavaScript
function selectTop(scored, topN, config) {
|
|
const eligible = scored.filter((item) => !item.excludedFromTop10);
|
|
const excluded = scored.filter((item) => item.excludedFromTop10);
|
|
|
|
const sorted = [...eligible].sort((a, b) => b.score - a.score);
|
|
|
|
const groupCap = Math.max(1, Math.ceil(topN * 0.5));
|
|
const groupCounts = {};
|
|
const firstPass = [];
|
|
const deferred = [];
|
|
|
|
for (const item of sorted) {
|
|
const count = groupCounts[item.group] || 0;
|
|
if (count < groupCap && firstPass.length < topN) {
|
|
firstPass.push(item);
|
|
groupCounts[item.group] = count + 1;
|
|
} else {
|
|
deferred.push(item);
|
|
}
|
|
}
|
|
|
|
let selected = firstPass;
|
|
if (selected.length < topN) {
|
|
selected = selected.concat(deferred.slice(0, topN - selected.length));
|
|
}
|
|
selected = selected.slice(0, topN);
|
|
|
|
const selectedIds = new Set(selected.map((item) => item.ticket.id));
|
|
const notSelected = sorted.filter((item) => !selectedIds.has(item.ticket.id));
|
|
|
|
return { selected, excluded: excluded.concat(notSelected) };
|
|
}
|
|
|
|
module.exports = { selectTop };
|