Skip to content

Instantly share code, notes, and snippets.

@Mix-Liten
Last active May 29, 2022 10:19
Show Gist options
  • Save Mix-Liten/63f08bd9199aa6090fdc04b8be160877 to your computer and use it in GitHub Desktop.
Save Mix-Liten/63f08bd9199aa6090fdc04b8be160877 to your computer and use it in GitHub Desktop.
JS Utility Functions
function randomNumberBetween(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
/**
* example: sleep(1000).then(() => { ...doSomeThing })
*/
function sleep(duration) {
return new Promise(resolve => {
setTimeout(resolve, duration)
})
}
/**
* cache method result
* example:
* const add = memoize((a, b) => a + b)
* add(2, 5) // 7 <- this result is cached
* add(2, 5) // 7 <- return cached value
*/
function memoize(cb) {
const cache = new Map()
return (...args) => {
const key = JSON.stringify(args)
if (cache.has(key)) return cache.get(key)
const result = cb(...args)
cache.set(key, result)
return result
}
}
/**
* example:
* const people = [{ name: "Kyle", age: 18 }, { name: "Mike", age: 18 }, { name: "Jill", age: 26 }]
* groupBy(people, "age") // { 18: [{ name: "Kyle", age: 18 }, { name: "Mike", age: 18 }], 26: [{ name: "Jill", age: 26 }] }
*/
function groupBy(array, key) {
return array.reduce((group, element) => {
const keyValue = element[key]
return { ...group, [keyValue]: [...(group[keyValue] ?? []), element] }
}, {})
}
const DIVISIONS = [
{ amount: 60, name: "seconds" },
{ amount: 60, name: "minutes" },
{ amount: 24, name: "hours" },
{ amount: 7, name: "days" },
{ amount: 4.34524, name: "weeks" },
{ amount: 12, name: "months" },
{ amount: Number.POSITIVE_INFINITY, name: "years" },
]
// locale "undefined" use environment(browser) default language, or specific like "en", "ja"
const RELATIVE_DATE_FORMATTER = new Intl.RelativeTimeFormat(undefined, { numeric: "auto" })
/**
* example:
* formatRelativeDate(new Date(new Date().setDate(25))) // 'in 3 weeks'
* formatRelativeDate(new Date(new Date().setDate(-25))) // '4 weeks ago'
*/
function formatRelativeDate(toDate, fromDate = new Date()) {
let duration = (toDate - fromDate) / 1000
for (let i = 0; i <= DIVISIONS.length; i++) {
const division = DIVISIONS[i]
if (Math.abs(duration) < division.amount) {
return RELATIVE_DATE_FORMATTER.format(Math.round(duration), division.name)
}
duration /= division.amount
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment