a collection of oneliners and other useful functions.
see also: a minimal testing library
# create an object mapping element ids to their corresponding dom elements
dom =
for a in document.querySelectorAll("[id]")
dom[a.id] = a
delete_duplicates = (a) -> [...new Set(a)]
random_integer = (min, max) -> Math.floor(Math.random() * (max - min + 1)) + min
random_element = (a) -> a[Math.floor(Math.random() * a.length)]
n_times = (n, f) -> Array.from({length: n}, (_, i) -> f(i))
sum = (a) -> a.reduce ((b, a) -> b + a), 0
mean = (a) -> sum(a) / a.length
intersection = (a, b) -> a.filter (c) -> b.includes c
is_function = (a) -> typeof a is "function"
is_string = (a) -> typeof a is "string"
is_plain_object = (a) -> a? and typeof a is "object" and a.constructor is Object
median = (a) ->
sorted = a.slice().sort((a, b) -> a - b)
sorted[Math.floor(sorted.length / 2)]
# add value to an array stored under key in object
object_array_add = (object, key, value) -> (object[key] ||= []).push value
# sort elements in array by the given example order in sorting
sort_by_array = (a, sorting) ->
a.sort (x, y) -> sorting.indexOf(x) - sorting.indexOf(y)
# delete duplicates while keeping the order the same
delete_duplicates_stable = (a) ->
seen = new Set()
a.filter((item) -> seen.has(item) ? false : (seen.add(item), true))
# array shuffle
randomize = (a) ->
for i in a.length - 1 .. 1
j = Math.floor(Math.random() * (i + 1))
[a[i], a[j]] = [a[j], a[i]]
a
plain_object_merge = (a, b) ->
for k, v of b
if @is_plain_object(v) and @is_plain_object(a[k])
a[k] = @object_merge a[k], v
else a[k] = v
a