Things I've written or seen that are good, but eventually didn't use.
Last active
October 6, 2021 14:47
-
-
Save renoirb/49e4dc04259a79cc023aa97f6dd3790a to your computer and use it in GitHub Desktop.
JavaScript utility functions bag
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function daysAgo (n = 1) { | |
const d = parseInt(n) || 0 | |
const dateObj = new Date() | |
if (isNaN(d)) { | |
return dateObj | |
} | |
return new Date(dateObj.setDate(dateObj.getDate() - d)) | |
} | |
/** | |
* Convert numbers to words. | |
* | |
* Refactored to make it less obscure. | |
* | |
* Original Copyright, 25th July 2006, by Stephen Chapman | |
* | |
* @param {number} s | |
* @return {string} word representation of a given number | |
*/ | |
function numberToWords(s) { | |
// American Numbering System | |
var thousies = ['', 'thousand', 'million', 'billion', 'trillion'] | |
// Or English | |
// var thousies = ['','thousand','million', 'milliard','billion']; | |
var unit = [ | |
'zero', | |
'one', | |
'two', | |
'three', | |
'four', | |
'five', | |
'six', | |
'seven', | |
'eight', | |
'nine', | |
] | |
var teenies = [ | |
'ten', | |
'eleven', | |
'twelve', | |
'thirteen', | |
'fourteen', | |
'fifteen', | |
'sixteen', | |
'seventeen', | |
'eighteen', | |
'nineteen', | |
] | |
var tweenies = [ | |
'twenty', | |
'thirty', | |
'forty', | |
'fifty', | |
'sixty', | |
'seventy', | |
'eighty', | |
'ninety', | |
] | |
s = s.toString() | |
s = s.replace(/[\, ]/g, '') | |
if (s != parseFloat(s)) { | |
return 'not a number' | |
} | |
var x = s.indexOf('.') | |
if (x == -1) { | |
x = s.length | |
} | |
if (x > 15) { | |
return 'too big' | |
} | |
var n = s.split('') | |
var str = '' | |
var sk = 0 | |
for (var i = 0; i < x; i++) { | |
if ((x - i) % 3 == 2) { | |
if (n[i] == '1') { | |
str += teenies[Number(n[i + 1])] + ' ' | |
i++ | |
sk = 1 | |
} else if (n[i] != 0) { | |
str += tweenies[n[i] - 2] + ' ' | |
sk = 1 | |
} | |
} else if (n[i] != 0) { | |
str += unit[n[i]] + ' ' | |
if ((x - i) % 3 == 0) { | |
str += 'hundred ' | |
} | |
sk = 1 | |
} | |
if ((x - i) % 3 == 1) { | |
if (sk) { | |
str += thousies[(x - i - 1) / 3] + ' ' | |
} | |
sk = 0 | |
} | |
} | |
return str.trim() | |
} | |
Keep Set of <things>
in LocalStorage
/**
* Sort function predicate.
*
* To help memory, here is the gist of how it should work;
*
* - If compareFunction(left, right) returns a value > than 0, sort right before left.
* - If compareFunction(left, right) returns a value < than 0, sort left before b.
* - If compareFunction(left, right) returns 0, left and right are considered equal.
*
* Source:
* - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
*/
export type ISortFnPredicate<T> = (left: T, right: T) => -1 | 1 | 0
/**
* Bucket in which to keep the decisions taken.
*
* One LocalStorage key per grouping.
*/
export interface ISetLocalStorageAdapter<T = string | number> {
readonly storageKey: string
readonly items: T[]
add(item: T): void
remove(item: T): void
}
export const createSetLocalStorageAdapter = <T = unknown>(
storageKey: string,
w: WindowProxy,
): ISetLocalStorageAdapter<T> => {
const initially = w.localStorage.getItem(storageKey)
const initiallyEmpty = initially === null
const duplicates = (items: T[]): T[] => {
const unique = new Set(items)
const collected = items.filter((k: T) => {
if (unique.has(k)) {
unique.delete(k)
return false
} else {
return true
}
})
return collected
}
const getItems = (k: string): T[] => {
const stringified = w.localStorage.getItem(k) ?? '[]'
const items: T[] = []
if (initiallyEmpty === false) {
try {
const parsed = JSON.parse(stringified) as T[]
items.push(...parsed)
} catch (e) {
console.log(
`Something went wrong on LocalStorage.getItem("${storageKey}")`,
e,
)
}
}
return items
}
// initial state at call time
const _initialStateItems: T[] = getItems(storageKey)
if (initiallyEmpty) {
w.localStorage.setItem(storageKey, JSON.stringify(_initialStateItems))
}
const out: ISetLocalStorageAdapter<T> = {
storageKey,
get items(): T[] {
const items = getItems(storageKey)
return items
},
add(item: T) {
const before = getItems(storageKey)
const items = before.filter((k: T) => k !== item).sort()
const foundDuplicates = duplicates(items)
if (foundDuplicates.includes(item)) {
console.log(`${storageKey} add(${item}), found duplicate, not adding`, {
foundDuplicates,
})
} else {
items.push(item)
w.localStorage.setItem(storageKey, JSON.stringify(items))
}
},
remove(item: T) {
const before = getItems(storageKey)
const items = before.filter((k: T) => k !== item).sort()
const foundDuplicates = duplicates(items)
if (foundDuplicates.includes(item)) {
console.log(`${storageKey} remove(${item}), found duplicate`, {
foundDuplicates,
})
}
w.localStorage.setItem(storageKey, JSON.stringify(items))
},
}
Object.freeze(out.storageKey)
return out
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Managing a bucket of sets