org.candelbio.multitool.core

Various generally useful utilities

*side-walk-context*

dynamic

<*

<=*

=*

>*

>=*

add-inverse

(add-inverse db children-att parent-att)

Given a db (map of maps), and a multi-valued attribute children-att, compute the single-valued inverse relationship as parent-att

add-inverse-multiple

(add-inverse-multiple db children-att parent-att)

Given a db (map of maps), and a multi-valued attribute children-att, compute the single-valued inverse relationship as parent-att

all-keys

(all-keys sheet-data)

Given a seq of maps, return the union of all keys

bag=

(bag= c1 c2)

True if c1 and c2 are equal considered as bags

bstr

(bstr thing)

Name or str of thing. Name means ‘better str’, better in some contexts anyway,

clean-map

(clean-map map)(clean-map map pred)

Remove values from ‘map’ based on applying ‘pred’ to value (default is nullish?).

clean-maps

(clean-maps map)(clean-maps pred map)

Remove values recursively from ‘map’ based on applying ‘pred’ to value (default is nullish?).

clean-seq

(clean-seq s)

Remove all nullish values from a seq

clean-walk

(clean-walk struct)(clean-walk struct pred)

Remove values from all maps in ‘struct’ based on ‘pred’ (default is nullish?).

coerce-boolean

(coerce-boolean v)

Coerce a value (eg a string from a web API) into a boolean

coerce-numeric

(coerce-numeric thing)

Attempt to turn thing into a number (long or double). Return number if succesful, otherwise original string

coerce-numeric-hard

(coerce-numeric-hard thing)

Coerce thing to a number if possible, otherwise return nil

collecting

Exec is a fn of one argument, which is called and passed another fn it can use to collect values; the collection is returned. See tests for example

collecting-merge

Exec is a fn of one argument, which is called and passed another fn it can use to collect values which are merged with merge-recursive; the result is returned. See tests for example TODO

comma-list

(comma-list list)

Splice the non-nullish elements of list together in a string, separated by ‘, ’

concatv

(concatv & args)

Concatenate vectors

contains-chars?

(contains-chars? bads s)

de-ns

(de-ns struct)

De-namespace. Remove the namespaces that backquote insists on adding. See tests for illustration.

def-lazy

macro

(def-lazy var & body)

Like def but produces a delay; value is acceessed via @ and won’t be computed until needed

default

(default map key val)

default-param-regex

defaulted

defn-memoized

macro

(defn-memoized name args & body)

Like defn, but produces a memoized function

dehumanize

(dehumanize map)

Convert string keys to keywords, recursively

delete-keys

(delete-keys map key-seq)

delete-subseq

(delete-subseq seq subseq)

dissoc-if

(dissoc-if f hashmap)

dissoc-in

(dissoc-in map [k & k-rest])

Dissoc in a nested map structure

dissoc-walk

(dissoc-walk struct & keys)

distinct*?

(distinct*? seq)

Given a seq, return true if all elements are distinct. See distinct?

distinctly

(distinctly coll keyfn)

Like distinct, but equality determined by keyfn

divide-map-by-value

(divide-map-by-value f map)

split map by whether (f v) is true or false

divide-with

(divide-with p coll)

doall-safe

(doall-safe thing)

Realize lazy sequences, if arg is such, otherwise acts as identity

doseq*

macro

(doseq* bindings & body)

Like doseq, but goes down lists in parallel rather than nested. Assumes lists are same size.

duplicates

(duplicates seq)

Return elements that occur more than once.

error-handling-fn

(error-handling-fn f)

Returns a fn that acts like f, but return value is (true result) or (false errmsg) in the case of an error

every-nth

(every-nth n coll)

expand-template

(expand-template template bindings & {:keys [param-regex key-fn], :or {param-regex default-param-regex, key-fn keyword}})

Template is a string containing {foo} elements, which get replaced by corresponding values from bindings. See tests for examples.

expand-template-recur

(expand-template-recur tmplate & args)

Like expand-template but will recurse, so the template replacements can contain parameters

expand-template-string

extend-seq

(extend-seq seq)

Return a seq padded out to infinity with nils

filter-rest

(filter-rest f seq)

A lazy sequence generated by applying f to seq and its tails

fix

(fix f)

Fixed-point combinator, useful in conjunction with memoization

following-elt

(following-elt elt seq)

for*

macro

(for* bindings & body)

Like for but goes down lists in parallel rather than nested. Assumes lists are same size.

forcat

macro

(forcat vars body)

forf

macro

(forf forms body)

Like for but filters out nullish? values

freq-map

(freq-map seq)

get*

(get* thing key)

get-in*

(get-in* thing keyseq)

glob->regex

(glob->regex s)

Takes a glob-format string and returns an equivalent regex.

group-by-and-transform

(group-by-and-transform by f seq)

Like group-by, but the values of the resultant map have f mapped over them

group-by-dups

(group-by-dups f seq)

Like group-by but return only groups with >1 member

group-by-multiple

(group-by-multiple f coll)

Like group-by, but f produces a seq of values rather than a single one; the orginal value gets grouped with each of them

hex-string

(hex-string n)

Output number as hex string

ignore-errors

macro

(ignore-errors & body)

Execute body; if an exception occurs ignore it and return nil. Note: strongly deprecated for production code.

ignore-report

macro

(ignore-report & body)

Execute body, if an exception occurs, print a message and continue

ignore-return

macro

(ignore-return & body)

Execute body, if an exception occurs, return it

index-by

(index-by f coll)

Return a map of the elements of coll indexed by (f elt). Similar to group-by, but overwrites elts with same index rather than producing vectors.

index-by-and-transform

(index-by-and-transform f g coll)

Return a map of the elements of coll indexed by (f elt) and transformed by (g elt).

index-by-multiple

(index-by-multiple f coll)

Like index-by, but f produces a seq of values rather than a single one

index-by-ordered

(index-by-ordered f coll)

Return an array map of the elements of coll indexed by (f elt), preserving the order. See index-by

index-by-safely

(index-by-safely f coll)

Return a map of the elements of coll indexed by (f elt). Throw an exception of there are duplicate keys.

insert-after

(insert-after seq elt after)

intercalate

(intercalate l1 l2)

Given 2 seqs, produce a seq with alternating elements.

into-string

(into-string thing)

Convert a set or seq of chars into a string. Like (into "" ) if that worked.

join-seq

(join-seq sep seq)

Like str/join but makes a list, useful for HTML generation

key-counter

keyword-conc

(keyword-conc & parts)

Concatenate parts (which are keywords, strings, anything acceptable to name) into a keyword

keyword-safe

(keyword-safe str)

Make a string into a readable keyword by replacing certain punctuation

keywordize

(keywordize map & keys)

Convert the values of selected keys to keywords

keywordize-keys

(keywordize-keys map)

labelize

(labelize s)

Convert - and _ to spaces

lconj

(lconj v e)

Conj a value to the front (left) of vector. Not performant

ldifference

(ldifference list1 list2)

Compute the set difference of list1 - `list2’

lintersection

(lintersection & lists)

Compute the intersection of lists

lunion

(lunion & lists)

Compute the union of lists

make-collecter

(make-collecter init collect-fn)

map-chunked

(map-chunked f chunk-size l)

Call f with chunk-sized subsequences of l, concat the results

map-diff

(map-diff a b)

Returns a recursive diff of two maps, which you will want to prettyprint.

map-entry

(map-entry k v)(map-entry [k v])

Make a map entry

map-invert-multiple

(map-invert-multiple m)

Returns the inverse of map with the vals mapped to the keys. Like set/map-invert, but does the sensible thing with multiple values. Ex: (map-invert-multiple {:a 1, :b 2, :c [3 4], :d 3}) ==>⇒ {2 #{:b}, 4 #{:c}, 3 #{:c :d}, 1 #{:a}}

map-key-values

(map-key-values f hashmap)

Map f over [k v] of hashmap, returning new v

map-keys

(map-keys f hashmap)

Map f over the keys of hashmap

map-keys-recursive

(map-keys-recursive f hashmap)

Map f over the keys of hashmap, and any nested hashmaps

map-values

(map-values f hashmap)

Map f over the values of hashmap

mapcatf

(mapcatf f & args)

Like mapcat but filters out nullish? values

mapf

(mapf f & args)

Like map but filters out nullish? values. Close to clojure.core/keep but uses different test.

mapx

(mapx f seq)

max*

max-by

(max-by keyfn seq)

Find the maximum element of seq based on keyfn

memoize-cache

(memoize-cache name)

Return the cache (map of args to values) for a named memoizer.

memoize-named

(memoize-named name f)

Like clojure.core/memoize, but retains a ptr to the cache so it can be cleared (see memoize-reset)

memoize-rec

macro

(memoize-rec form)

memoize-reset!

(memoize-reset!)(memoize-reset! name)

Clear the cache of one or all memoized fns

memoizer-stats

(memoizer-stats)

Return information about all memoize-name fns

memoizers

merge-in

(merge-in map [k & k-rest] changes)

Merge in a nested map structure

merge-recursive

(merge-recursive m1 m2)

Recursively merge two arbitrariy nested map structures. Terminal seqs are concatentated, terminal sets are merged.

merge-recursive-with

(merge-recursive-with f m1 m2)

Recursively merge two arbitrariy nested map structures, merging terminals (non-maps) with f

min*

min-by

(min-by keyfn seq)

Find the minimum element of seq based on keyfn

n-chars

negate

(negate f)

neighborhood

(neighborhood from n neighbors)

Computes the neighborhood of radius n from from, neighbors is a function that produces the immediate neighbors

nullify

(nullify v)

Convert nullish values to nil

nullish?

(nullish? v)

True if value is something we probably don’t care about (nil, false, empty seqs, empty strings)

numeric-prefix-sort-key

(numeric-prefix-sort-key s)

Provide a key for sorting strings with leading numbers

oneof

(oneof & things)

true if exactly one of its arguments is non-nil.

or-nil

(or-nil pred)

Given a 1-arg pred, return a new fn that acts as identity if pred is true, nil otherwise

ordinal

(ordinal n)

Ordinal string for number n, eg 123 → “123rd”

ordinal-suffix

(ordinal-suffix n)

The suffix for the ordinal version of n

pam

Map backwards. Like map, but takes its args in inverse order. useful in conjunction with ->

param-regex-double-braces

param-regex-javascript

partition-diff

(partition-diff f coll)

Partition coll between v1 and v2 at points for which (f v1 v2) is true

partition-if

(partition-if f coll)

Partition coll at every v for which (f v) is true

pattern-match

(pattern-match pat thing)

Ultra-simple structure pattern matcher. Variables are (? ), bindings

pivot

(pivot mapseq row-id-col row-id-field pivot-key-field pivot-value-field)

position

(position pred coll)

Returns the first index of coll for which pred is true

position=

(position= elt coll & [key-fn])

Returns the first index of coll that equals elt

positions

(positions pred coll)

Returns a list of indexes of coll for which pred is true

positions=

(positions= elt coll & [key-fn])

Return list of indexes of coll that equals elt

powerset

(powerset s)

Compute the powerset of a set

preceding-elt

(preceding-elt elt seq)

present?

(present? v)

punc-chars

rand-around

(rand-around p range)

Return a random float within range of p

rand-range

(rand-range a b)

Return a random float between a and b

rand-range-int

(rand-range-int a b)

Return a random int between a and b

random-element

(random-element seq)

Return a random element from a seq

random-elements

(random-elements n seq)

Return n random elements from a seq

range-truncate

(range-truncate v lower upper)

Return the closest value to v within range [lower, upper]

re-pattern-literal

(re-pattern-literal string)

Return a regex that will match the literal string

re-quote

(re-quote s)

re-seq-positions

(re-seq-positions re s & [group])

Returns a lazy sequence of successive matches of pattern in string, returning [start end] pairs

re-substitute

(re-substitute re s subfn)(re-substitute re s)

Match re against s, apply subfn to matching substrings. Return list of fragments, processed and otherwise

real-vector?

(real-vector? thing)

True iff thing is a real vector. Shouldn’t be necessary, but (vector? (first {:a 1})) ⇒ true. Most useful for walker fns.

remove-nil-values

(remove-nil-values hashmap)

remove=

(remove= elt seq & [key-fn])

Remove occurences of elt in seq, applying key-fn before testing if supplied

rename-key

(rename-key map from to)

repeat-until

(repeat-until pred f start)

Iterate f on start until a value is produced that passes pred, returns value.

rest-while

(rest-while pred coll)

Like take-while but applies pred to successive tails of the seq, and returns a seq of tails

round

(round n)

Round the argument

safe-name

(safe-name thing)

safe-nth

(safe-nth col n)

Like nth but will return nil if out of bounds rather than erroring

safely

(safely f)

Given f, produce new function that permits nulling.

saferly

(saferly f)

Given f, produce new function that will return nils if exception is thrown. Not recommended for production code

safestly

(safestly f)

Given f, produce new function that will return original if exception is thrown. Not recommended for production code

sconj

(sconj coll elt)

Like conj but will always create a set.

select-by

(select-by seq prop val)

self-label

(self-label attr hashmap)

Given a map HASHMAP with maps as values, adds the index to each value as the value of attriute ATTR

separate

(separate pred coll)

Separate coll into two collections based on pred.

sequencify

(sequencify thing)

Turn thing into a sequence if it already isn’t one

set=

(set= c1 c2)

True if c1 and c2 are equal considered as sets

side-walk

(side-walk f form)

Walks form, an arbitrary data structure, evaluating f on each element for side effects. Note: has nothing to do with the standard (functional) walker, and maybe should have a different name (traverse?)

side-walk-find-paths

(side-walk-find-paths pred form)

side-walk-paths

(side-walk-paths f form path)(side-walk-paths f form)

some-thing

(some-thing pred seq)

Like some, but returns the original value of the seq rather than the result of the predicate.

sort-map-by-values

(sort-map-by-values m)

sort-map-by-values-fn

(sort-map-by-values-fn f m)

sort-with-numeric-prefix

(sort-with-numeric-prefix seq)

Sort a seq of strings, treating leading numbers in a sane way

str-replace-multiple

(str-replace-multiple map string)

stratify

(stratify g predecessors depth-prop)

g is a map, predecessors is a function of g values to g indices. computes for each node the depth: if no predecssors 0, otherwise (inc (max (depth predecssors))) useful for laying out DAGs, possibly elsewhere

string-includes-uncased?

(string-includes-uncased? s substr)

Case insensitive version of str/includes?

strip-chars

(strip-chars removed s)

Removes every character of a given set from a string

subseqs

(subseqs seq i)

Returns a seq of all i-length subseqs

substitute

(substitute struct vmap)

vmap defines a substitution; Walk struct, replacing any keys that appear in vmap with corresponding value.

substitute-gen

(substitute-gen struct vmap generator)

Like substitute, but for any terminal elements not in map, call generator on first occurance to generate a value.

swapped

(swapped f)

Return a fn like f but with first two arguments swapped

throwable?

(throwable? x)

transitive-closure

(transitive-closure f)

f is a fn of one arg that returns a list. Returns a new fn that computes the transitive closure of f.

transpose

(transpose matrix)

trim-chars

(trim-chars removed s)

Removes every character of a given set from the ends of a string

trim-chars-left

(trim-chars-left removed s)

Removes every character of a given set from the left end of a string

trim-chars-right

(trim-chars-right removed s)

Removes every character of a given set from the right end of a string

trueish?

(trueish? x)

truncate-string

(truncate-string s n)

truthy?

(truthy? x)

Return false if x is nil or false, true otherwise

uncollide

(uncollide seq & {:keys [key-fn new-key-fn existing], :or {key-fn identity, new-key-fn (fn* [p1__4434#] (str p1__4434# "-1")), existing #{}}})

Given a seq, return a new seq where the elements are guaranteed unique (relative to key-fn), using new-key-fn to generate new elements

underscore->camelcase

(underscore->camelcase s)

Convert foo_bar into fooBar

union-by

(union-by f s1 s2)

Return unique elements in (union s1 s2) given f as identity key

unique-key

(unique-key root)

Produce a unique keyword based on root.

unique-relative-to

(unique-relative-to s existing suffix)

Generate a name based on s, that is not already found in existing.

unlist

(unlist thing)

unmap

(unmap m key-key)

update!

(update! map k f & args)

update-some-keys

(update-some-keys map f & keys)

validate-template

(validate-template template fields & {:keys [param-regex], :or {param-regex default-param-regex}})

Validate a template, defined as in expand-template-string; fields is a set of allowed field names

vdelete=

(vdelete= elt v)

vectorize

(vectorize f)

Given a fn f with scalar args, (vectorized f) is a fn that takes either scalars or vectors for any argument, doing the appropriate vectorization. All vector args should be the same length.

walk-all-keys

(walk-all-keys f thing)

Walk all the keywords in thing recursively

walk-collect

(walk-collect f thing)

Walk f over thing and return a list of the non-nil returned values

walk-filtered

(walk-filtered f thing filter)

Walk thing, applying f to every object that passes filter

walk-find

(walk-find f thing)

Walk over thing and return the first val for which f is non-nil

walk-keys

(walk-keys f keys thing)

Walk all the map entries in thing matching key (a key or set)

walk-map-entries

(walk-map-entries f thing)

Walk all the map entries in thing

walk-reduce

(walk-reduce f form init)

Walks form with an accumulator. f is a function of [accumulator elt], init is initial val of accumulator.

xor

(xor a b)

boolean a xor b