Appearance
Javascript (JS) Snippets
A place for me to pop useful or interesting JS snippets.
Debouncing
Debouncing in javascript, really useful when you wan't to stop and event firing too often. E.g. listening to key inputs.
js
// Debounce function
const debounce = (fn, delay = 300) => {
let timerId = null;
return (...args) => {
clearTimeout(timerId);
timerId = setTimeout(() => fn(...args), delay);
};
};Pick Random From and Array
Modelled on the {array}.pick() function in gdscript.
js
// Picks a random item from array
function pickArrayRandom(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}Pick Random From and Object
Modelled on the {array}.pick() function in gdscript.
js
// Picks a random item from array
function pickObjectRandom(obj) {
const keys = Object.keys(obj);
return keys[Math.floor(Math.random() * keys.length)];
}Get a random sub array from parent array
js
// Get a random array of n length from the parent array
function randomSubset(n, arr) {
const shuffled = array.sort(() => 0.5 - Math.random());
return shuffled.slice(0, n);
}Random integer
js
const randomInt = (low = 1, high = 6) => {
return Math.floor(Math.random() * (high - low + 1) + low);
};Random float
js
const randomFloat = (low = 0, high = 1, digits = 1) => {
let val = Math.random() * (high - low) + low; // this will get a number between low and high;
return +val.toFixed(digits);
};Random between
JS
// Inclusive
function randomBetween(min = 0, max = min, digits = 0) {
const result = min + (max - min) * Math.random();
return result.toFixed(digits);
}Rolling a dice
JS
function rollDice(sides, modifier = 0) {
return Math.floor(Math.random() * sides) + 1 + modifier;
}Is even
Yeah I know this is basic...shut up.
JS
export function isEven(number) {
return number % 2 === 0; //returns true or false!
}Ordinal
Function to get the ordinal description of an integer.
JS
export function ordinal(number) {
const rule = new Intl.PluralRules("en-gb", { type: "ordinal" });
// rule.select returns one of the following
const ordinals = {
one: "st",
two: "nd",
few: "rd",
many: "th",
zero: "th",
other: "th",
};
return `${number}${ordinals[rule.select(number)]}`;
}Roll20 Style roll parsing
This assumes you've also got the rollDice function.
JS
// function to parse roll strings a la roll20
export function parseRollString(inputStr) {
const str = inputStr.toLowerCase();
const keepTypes = ["kl", "kh"];
const operators = ["+", "-"];
let result = 0;
// check the string is valid
const regTest = /([\d]+d[\d]+)([-+*/]{1}[\d]+)?((kl|kh){1}\d+)?/i;
if (regTest.test(str) == false) {
console.warn("Invalid string");
return false;
}
// split the string
const reg = /(\d)+|d|(kl)|(kh)|[+\-*/]/gi;
const match = str.match(reg);
const data = {
str,
rollCount: Number(match[0]),
dice: Number(match[2]),
rolls: [],
};
// if there is a modifer
if (operators.includes(match[3])) {
data.operator = match[3];
data.operatorValue = Number(match[4]);
}
// if there is a modifier and keepType
if (keepTypes.includes(match[5])) {
data.keepType = match[5];
data.keep = Number(match[6]);
}
// if there is no modifer but a keepType
if (keepTypes.includes(match[3])) {
data.keepType = match[3];
data.keep = Number(match[4]);
}
// roll the dice & apply modifier
for (let i = 1; i <= data.rollCount; i++) {
const initial = rollDice(data.dice); // don't add modifer here!!! 😱😱
const roll = { initial, value: initial };
if ("operator" in data) {
roll.value = roll.initial + Number(data.operator + data.operatorValue);
}
data.rolls.push(roll);
}
// may as well calc the result for basic rolls
result = data.rolls.reduce((a, c) => a + c.value, 0);
// create an ordered copy of rolls in desc order
const sortedRolls = data.rolls.toSorted((a, b) => b.value - a.value);
data.rolls = sortedRolls
console.log(sortedRolls)
if (data.keepType == "kl") {
data.kept = sortedRolls.slice(-data.keep);
result = data.kept.reduce((a, c) => a + c.value, 0);
}
if (data.keepType == "kh") {
data.kept = sortedRolls.slice(0, data.keep);
result = data.kept.reduce((a, c) => a + c.value, 0);
}
return { value: result, data };Object key by weight
js
// Selects a key from an object assuming the value is it's weight.
export function keyByWeight(obj) {
const totalWeight = Object.values().reduce((a, val) => a + val, 0);
const randomChance = Math.floor(Math.random() * totalWeight);
let currentMax = 0;
let result;
for (const d of Object.keys(obj)) {
currentMax += obj[d];
if (randomChance <= currentMax) {
result = d;
break;
}
}
return result;
}Convert string into HTML
Really useful, but be aware of Cross Site Scripting. Ref: Wesbos: HTML from Strings and XSS
js
const myHTML = `<div>Magic beans!<div>`;
const myFragment = document.createRange().createContextualFragment(myHTML);Basic numerical IDs
This will make a JS generator function (thats what the function* does), the function will keep track of it's last yield and increment the number each time the function runs. Closer to DB ids than anything else.
JS
function* idGenerator(start = 0) {
let index = start;
while (true) {
yield index++;
}
}
const gen = idGenerator();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3