org.candelbio.multitool.core
Various generally useful utilities
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
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-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 ‘, ’
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
defn-memoized
macro
(defn-memoized name args & body)
Like defn
, but produces a memoized function
distinct*?
(distinct*? seq)
Given a seq, return true if all elements are distinct. See distinct?
divide-map-by-value
(divide-map-by-value f map)
split map by whether (f v) is true or false
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.
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
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
filter-rest
(filter-rest f seq)
A lazy sequence generated by applying f to seq and its tails
for*
macro
(for* bindings & body)
Like for but goes down lists in parallel rather than nested. Assumes lists are same size.
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-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
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
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.
into-string
(into-string thing)
Convert a set or seq of chars into a string. Like (into ""
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
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-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-keys-recursive
(map-keys-recursive f hashmap)
Map f over the keys of hashmap, and any nested hashmaps
mapf
(mapf f & args)
Like map but filters out nullish? values. Close to clojure.core/keep but uses different test.
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-reset!
(memoize-reset!)
(memoize-reset! name)
Clear the cache of one or all memoized fns
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
neighborhood
(neighborhood from n neighbors)
Computes the neighborhood of radius n from from, neighbors is a function that produces the immediate neighbors
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
or-nil
(or-nil pred)
Given a 1-arg pred, return a new fn that acts as identity if pred is true, nil otherwise
pam
Map backwards. Like map, but takes its args in inverse order. useful in conjunction with ->
partition-diff
(partition-diff f coll)
Partition coll between v1 and v2 at points for which (f v1 v2) is true
pattern-match
(pattern-match pat thing)
Ultra-simple structure pattern matcher. Variables are (?
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-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=
(remove= elt seq & [key-fn])
Remove occurences of elt in seq, applying key-fn before testing if supplied
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
safe-nth
(safe-nth col n)
Like nth but will return nil if out of bounds rather than erroring
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
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
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?)
some-thing
(some-thing pred seq)
Like some, but returns the original value of the seq rather than the result of the predicate.
sort-with-numeric-prefix
(sort-with-numeric-prefix seq)
Sort a seq of strings, treating leading numbers in a sane way
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?
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.
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.
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
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
union-by
(union-by f s1 s2)
Return unique elements in (union s1 s2) given f as identity key
unique-relative-to
(unique-relative-to s existing suffix)
Generate a name based on s, that is not already found in existing.
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
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-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-reduce
(walk-reduce f form init)
Walks form with an accumulator. f is a function of [accumulator elt], init is initial val of accumulator.