Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
import { type Money, money } from "./money_amount.ts"; ← from money.amount ^1.0.0 · built alongside by fune
/**
* Split `amount` across `ratios` so the parts add back up to the whole.
*
* Splitting 10.00 three ways gives 3.34, 3.33, 3.33 - never 3.33 three times
* with a penny quietly lost. The leftover goes to the largest remainders,
* ties broken by position, so the split is stable and reproducible.
*/
export function allocate(amount: Money, ratios: readonly number[]): readonly Money[] {
if (ratios.length === 0) {
throw new RangeError("allocate needs at least one ratio");
}
if (!ratios.every((r) => Number.isInteger(r))) {
throw new TypeError("ratios must be integers");
}
const total = ratios.reduce((sum, r) => sum + r, 0);
if (total === 0) {
throw new RangeError("ratios must not sum to zero");
}
const shares = ratios.map((ratio) => {
const numerator = amount.minor * ratio;
const base = Math.floor(numerator / total);
return { base, remainder: numerator - base * total };
});
let leftover = amount.minor - shares.reduce((sum, s) => sum + s.base, 0);
const order = shares
.map((share, index) => ({ index, remainder: share.remainder }))
.sort((a, b) => b.remainder - a.remainder || a.index - b.index);
for (const { index } of order) {
if (leftover <= 0) break;
shares[index].base += 1;
leftover -= 1;
}
return shares.map((share) => money(share.base, amount.currency));
}