Skip to content

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