2024-12-08

coffeescript

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