Number
Utilities for clamping, generating, and aggregating numbers. Import from the root or from koyojs/Number.
// Root import
import { clamp, randomInt, sum } from "koyojs";
// Per-module import
import { clamp } from "koyojs/Number";Clamps a number between a minimum and maximum value. If the value is below min it returns min; if it is above max it returns max; otherwise it returns the value unchanged. Throws a RangeError if min > max.
| Parameter | Type | Description |
|---|---|---|
value | number | The number to clamp. |
min | number | Lower bound (inclusive). Must be ≤ max. |
max | number | Upper bound (inclusive). Must be ≥ min. |
| returns | number | — |
import { clamp } from "koyojs";
clamp(150, 0, 100); // 100 — above max, capped
clamp(-5, 0, 100); // 0 — below min, floored
clamp(42, 0, 100); // 42 — in range, returned as-is
// Volume slider — keep within 0–100%
const volume = clamp(rawInput, 0, 100);
// CSS opacity — must stay in 0.0–1.0
const opacity = clamp(userAlpha / 255, 0, 1);
// Pagination — never below page 1 or above the last page
const page = clamp(requestedPage, 1, totalPages);
// Restrict canvas drawing coordinates to viewport
const x = clamp(pointerX, 0, canvas.width);
const y = clamp(pointerY, 0, canvas.height);Returns a random integer between min and max, both inclusive. Uses Math.random internally — suitable for UI and game purposes, not cryptographic use. Throws a TypeError if either argument is not an integer, and a RangeError if min > max.
| Parameter | Type | Description |
|---|---|---|
min | number | Lower bound (inclusive). Must be an integer and ≤ max. |
max | number | Upper bound (inclusive). Must be an integer and ≥ min. |
| returns | number | — |
import { randomInt } from "koyojs";
randomInt(1, 6); // 1 | 2 | 3 | 4 | 5 | 6 — simulates a die
randomInt(0, 100); // any integer from 0 to 100
// Pick a random item from an array
const fruits = ["apple", "banana", "cherry", "mango"];
const pick = fruits[randomInt(0, fruits.length - 1)];
// Generate a 6-digit numeric OTP (UI placeholder / demo only)
const otp = randomInt(100000, 999999).toString();
// Randomize a stagger delay for animations (0–300 ms)
cards.forEach(card => {
card.style.animationDelay = `${randomInt(0, 300)}ms`;
});
// Shuffle an array using Fisher-Yates
function shuffle<T>(arr: T[]): T[] {
const a = [...arr];
for (let i = a.length - 1; i > 0; i--) {
const j = randomInt(0, i);
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}Returns the sum of all numbers in an array. Returns 0 for an empty array.
| Parameter | Type | Description |
|---|---|---|
values | number[] | The array of numbers to sum. |
| returns | number | — |
import { sum } from "koyojs";
sum([1, 2, 3, 4, 5]); // 15
sum([]); // 0
sum([-1, 1]); // 0
sum([0.1, 0.2]); // 0.30000000000000004 — standard JS float precision
// Shopping cart total
const cart = [
{ name: "Keyboard", price: 89.99 },
{ name: "Mouse", price: 39.99 },
{ name: "Monitor", price: 349.00 },
];
const total = sum(cart.map(item => item.price)); // 478.98
// Aggregate daily visitor counts
const week = [120, 240, 310, 180, 95, 410, 280];
const weeklyTotal = sum(week); // 1635
// Calculate total hours from a timesheet
const hours = entries.map(e => e.duration);
const totalHours = sum(hours);Returns the arithmetic mean of an array of numbers. Throws a RangeError if the array is empty — guard against empty input before calling.
| Parameter | Type | Description |
|---|---|---|
values | number[] | A non-empty array of numbers. |
| returns | number | — |
import { average } from "koyojs";
average([1, 2, 3]); // 2
average([10, 20, 30]); // 20
average([7]); // 7
average([1, 2]); // 1.5
// ⚠️ Throws RangeError on an empty array — always guard first
const score = scores.length > 0 ? average(scores) : null;
// Star rating display
const reviews = [4, 5, 3, 4, 5, 4, 2];
const rating = average(reviews).toFixed(1); // "3.9"
// Dashboard metric — average response time
const latencies = requests.map(r => r.durationMs);
const avgMs = average(latencies);
console.log(`Average response: ${avgMs.toFixed(0)}ms`);
// Normalize scores to a 0–10 scale
const normalized = rawScores.map(s => clamp(average(rawScores) - s + 5, 0, 10));Returns true if the integer is even. Throws a TypeError if the argument is not an integer.
| Parameter | Type | Description |
|---|---|---|
value | number | An integer to test. |
| returns | boolean | — |
import { isEven } from "koyojs";
isEven(4); // true
isEven(7); // false
isEven(0); // true
isEven(-2); // true
isEven(-3); // false
// Zebra-stripe table rows
rows.map((row, i) => (
<tr class={isEven(i) ? "row-light" : "row-dark"}>{...}</tr>
));
// Alternate card layout in a masonry grid
items.map((item, i) => ({
...item,
alignSelf: isEven(i) ? "flex-start" : "flex-end",
}));
// Split an array into even-indexed and odd-indexed items
const evens = arr.filter((_, i) => isEven(i));
const odds = arr.filter((_, i) => !isEven(i));Returns true if the integer is odd. Implemented as `!isEven(value)` — also throws a TypeError for non-integers.
| Parameter | Type | Description |
|---|---|---|
value | number | An integer to test. |
| returns | boolean | — |
import { isOdd } from "koyojs";
isOdd(3); // true
isOdd(4); // false
isOdd(-1); // true
isOdd(0); // false
// Show a divider after every odd item in a list
items.map((item, i) => (
<>
<Item data={item} />
{isOdd(i + 1) && i < items.length - 1 && <Divider />}
</>
));
// Group items into pairs (first of each pair is at an odd 1-based index)
const pairs = items.reduce<(typeof items)[]>((acc, item, i) => {
if (isOdd(i + 1)) acc.push([item]);
else acc[acc.length - 1].push(item);
return acc;
}, []);