Useful row/map/record related functions.
Useful row/map/record related functions.
(bastardify a-something)
Take something, string it and keywordify it, underscores for hyphens.
DEPRECATED! Consider: camel-snake-kebab.core/->snake_case_keyword
Why?
Underscores are OK for things like H2, hyphens? Not so much.
How?
(bastardify "Account: OPEX") => :account_opex
Take something, string it and keywordify it, underscores for hyphens. DEPRECATED! Consider: camel-snake-kebab.core/->snake_case_keyword Why? Underscores are OK for things like H2, hyphens? Not so much. How? (bastardify "Account: OPEX") => :account_opex
(bespoke-header a-map)
(bespoke-header base-header a-map)
(bespoke-header base-header strict? a-map)
Accepts vector and a map, returns header vector derived from both.
Header consists of base-header and remaining keys from the map, sorted.
If strict: base-header must be a subset of keys in the map, otherwise ExceptionInfo. If not strict then just 'do your best'.
If only given the map - returns vector of keys.
Why?
You don't want to use data, but you want some key columns first.
How?
(bespoke-header [:x :y :z] {:state :resting :x 0 :y 0 :z 0}) => [:x :y :z :state] (bespoke-header [:x :y :z :cycle] {:state :resting :x 0 :y 0 :z 0}) => [:x :y :z :cycle :state] (bespoke-header [:x :y :z :cycle] true {:state :resting :x 0 :y 0 :z 0}) => clojure.lang.ExceptionInfo: Missing keys in header?
Accepts vector and a map, returns header vector derived from both. Header consists of base-header and remaining keys from the map, sorted. If strict: base-header must be a subset of keys in the map, otherwise ExceptionInfo. If not strict then just 'do your best'. If only given the map - returns vector of keys. Why? You don't want to use data, but you want some key columns first. How? (bespoke-header [:x :y :z] {:state :resting :x 0 :y 0 :z 0}) => [:x :y :z :state] (bespoke-header [:x :y :z :cycle] {:state :resting :x 0 :y 0 :z 0}) => [:x :y :z :cycle :state] (bespoke-header [:x :y :z :cycle] true {:state :resting :x 0 :y 0 :z 0}) => clojure.lang.ExceptionInfo: Missing keys in header?
Compatibility shim for de-recordify, see maps->vecs.
Compatibility shim for de-recordify, see maps->vecs.
(default-parallel-n)
Return advised parallel workload. Logical processor count + 2.
How?
(default-parallel-n) => 10
Return advised parallel workload. Logical processor count + 2. How? (default-parallel-n) => 10
(field-unpacker delimiter field)
See if field contains a str/char delimiter, if so -- tries to parse as CSV.
Why?
Sometimes your fields have fields. (So many fields, fields for days.)
How?
(field-unpacker , "ala,ma,kota") => ["ala", "ma", "kota"]
See if field contains a str/char delimiter, if so -- tries to parse as CSV. Why? Sometimes your fields have fields. (So many fields, fields for days.) How? (field-unpacker \, "ala,ma,kota") => ["ala", "ma", "kota"]
(fixed-width-split fields)
Accept vector of slice sizes, returns function that will cut String.
Why?
Because somebody thought fixed width data records are a good thing.
How?
((fixed-width-split [4 3 4]) "Ala ma Kota.") => ["Ala " "ma " "Kota"]
Accept vector of slice sizes, returns function that will cut String. Why? Because somebody thought fixed width data records are a good thing. How? ((fixed-width-split [4 3 4]) "Ala ma Kota.") => ["Ala " "ma " "Kota"]
(friendlify a-something)
Take Clojure object and try to make a pretty String from its Class.
Why?
Display function name at runtime, but similar to how it looks in code.
How?
(friendlify friendlify) => "szew.io.util/friendlify"
Take Clojure object and try to make a pretty String from its Class. Why? Display function name at runtime, but similar to how it looks in code. How? (friendlify friendlify) => "szew.io.util/friendlify"
(getter a-key)
(getter a-key default)
Takes key and default value, returns a function that gets it.
Why?
Builtin get takes collection as first argument, this is the other way around.
How?
(mapv (getter :yolo :no) [{:yolo :yes} {:wat? :wat}]) => [:yes :no] (meta (getter :yolo :no)) => {:key :yolo, :default :no} (mapv (getter 0 :no) [[:yes] []]) => [:yes :no] (meta (getter 1 :no)) => {:key 1, :default :no}
Takes key and default value, returns a function that gets it. Why? Builtin get takes collection as first argument, this is the other way around. How? (mapv (getter :yolo :no) [{:yolo :yes} {:wat? :wat}]) => [:yes :no] (meta (getter :yolo :no)) => {:key :yolo, :default :no} (mapv (getter 0 :no) [[:yes] []]) => [:yes :no] (meta (getter 1 :no)) => {:key 1, :default :no}
(juxt-map & keys-fns)
Give keys and values, get a juxt map of keys-values. Hint: zipmap over juxt.
How?
((juxt-map :+ inc :- dec := identity) 2) => {:+ 3, :- 1, := 2}
Give keys and values, get a juxt map of keys-values. Hint: zipmap over juxt. How? ((juxt-map :+ inc :- dec := identity) 2) => {:+ 3, :- 1, := 2}
(keywordify a-something)
Take something, take string of it, then make it into keyword.
DEPRECATED! Consider: camel-snake-kebab.core/->kebab-case
Why?
Sometimes you just need a keyword that looks semi decent.
How?
(keywordify "Account: OPEX") => :account-opex
Take something, take string of it, then make it into keyword. DEPRECATED! Consider: camel-snake-kebab.core/->kebab-case Why? Sometimes you just need a keyword that looks semi decent. How? (keywordify "Account: OPEX") => :account-opex
(map->vec header mapped)
(map->vec defaults header mapped)
Takes header vector and map. Returns vector with meta. Allows defaults.
Why?
Singular version of maps->vecs, with inputs attached as meta.
How? (map->vec [:k1 :k2] {:k1 1, :k2 2}) => [1 2] (map->vec {:kx 100} [:k1 :k2 :kx] {:k1 1, :k2 2}) => [1 2 100] (meta (map->vec {:kx 100} [:k1 :k2 :kx] {:k1 1 :k2 2})) => {:defaults {:kx 100}, :header [:k1 :k2 :kx], :mapped {:k1 1, :k2 2}}
Takes header vector and map. Returns vector with meta. Allows defaults. Why? Singular version of maps->vecs, with inputs attached as meta. How? (map->vec [:k1 :k2] {:k1 1, :k2 2}) => [1 2] (map->vec {:kx 100} [:k1 :k2 :kx] {:k1 1, :k2 2}) => [1 2 100] (meta (map->vec {:kx 100} [:k1 :k2 :kx] {:k1 1 :k2 2})) => {:defaults {:kx 100}, :header [:k1 :k2 :kx], :mapped {:k1 1, :k2 2}}
(maps->vecs a-seq)
(maps->vecs head tails)
(maps->vecs defaults head tails)
Takes header vector and maps, returns seq of vectors.
Vector maps tails over head. Defaults are done by merging before mapping.
Why?
Because maps are so nice, but it's also nice to be able to dump them back.
How?
(maps->vecs [[:k1 :k2] {:k1 1, :k2 2}]) => ([1 2]) (maps->vecs [:k1 :k2] [{:k1 1, :k2 2}]) => ([1 2]) (maps->vecs {:kx 100} [:k1 :k2 :kx] [{:k1 1, :k2 2}]) => ([1 2 100]) (maps->vecs [:k1 :k2] [{:k1 1, :k2 2} {:k1 1, :k2 0}]) => ([1 2] [1 0])
Takes header vector and maps, returns seq of vectors. Vector maps tails over head. Defaults are done by merging before mapping. Why? Because maps are so nice, but it's also nice to be able to dump them back. How? (maps->vecs [[:k1 :k2] {:k1 1, :k2 2}]) => ([1 2]) (maps->vecs [:k1 :k2] [{:k1 1, :k2 2}]) => ([1 2]) (maps->vecs {:kx 100} [:k1 :k2 :kx] [{:k1 1, :k2 2}]) => ([1 2 100]) (maps->vecs [:k1 :k2] [{:k1 1, :k2 2} {:k1 1, :k2 0}]) => ([1 2] [1 0])
(maps-maker)
(maps-maker head tails)
Create maps-maker over two functions of input sequence: head and tails.
Defaults: head is first row as kebab-case-keyword vector, tails is rest.
Why?
Because it's a common scenario. I wrote it too many times by hand.
How?
((maps-maker) [["X" "Y"] [0 0] [1 1] [10 10]]) => ({:x 0 :y 0} {:x 1 :y 1} {:x 10 :y 10})
Create maps-maker over two functions of input sequence: head and tails. Defaults: head is first row as kebab-case-keyword vector, tails is rest. Why? Because it's a common scenario. I wrote it too many times by hand. How? ((maps-maker) [["X" "Y"] [0 0] [1 1] [10 10]]) => ({:x 0 :y 0} {:x 1 :y 1} {:x 10 :y 10})
(ppfilter n p)
(ppfilter n f coll)
Parametrized parallel filter, with max of n threads at once.
Accepts number of threads n, predicate p and a collection. If no collection is provided it produces a stateful transducer.
How?
(vec (filter odd? [1 2 3])) => [1 3] (vec (ppfilter 1 odd? [1 2 3])) => [1 3]
Parametrized parallel filter, with max of n threads at once. Accepts number of threads n, predicate p and a collection. If no collection is provided it produces a stateful transducer. How? (vec (filter odd? [1 2 3])) => [1 3] (vec (ppfilter 1 odd? [1 2 3])) => [1 3]
(ppmap n f)
(ppmap n f coll)
(ppmap n f coll & colls)
Parametrized parallel map. Like pmap, but with max of n threads at once.
Accepts number of threads n, function f and collections. If no collections are provided it produces a stateful transducer.
How?
(vec (map inc [1 2 3])) => [2 3 4] (vec (ppmap 1 inc [1 2 3])) => [2 3 4]
Parametrized parallel map. Like pmap, but with max of n threads at once. Accepts number of threads n, function f and collections. If no collections are provided it produces a stateful transducer. How? (vec (map inc [1 2 3])) => [2 3 4] (vec (ppmap 1 inc [1 2 3])) => [2 3 4]
Compatibility shim for recordify, see vecs->maps.
Compatibility shim for recordify, see vecs->maps.
(roll-in seq-of-seqs)
(roll-in agg seq-of-seqs)
Take sequence of sequences, last item is value, butlast items are a key. Return map of maps.
If agg callable is given -- it's used with update-in, otherwise entries action is assoc-in.
How?
(roll-in [[:a :b 3] [:a :c 4] [:x :z 0]]) => {:a {:b 3 :c 4} :x {:z 0}} (roll-in (fnil + 0) [[:a :b 3] [:a :c 4] [:x :z 0] [:a :c 2]]) => {:a {:b 3 :c 6} :x {:z 0}}
Take sequence of sequences, last item is value, butlast items are a key. Return map of maps. If agg callable is given -- it's used with update-in, otherwise entries action is assoc-in. How? (roll-in [[:a :b 3] [:a :c 4] [:x :z 0]]) => {:a {:b 3 :c 4} :x {:z 0}} (roll-in (fnil + 0) [[:a :b 3] [:a :c 4] [:x :z 0] [:a :c 2]]) => {:a {:b 3 :c 6} :x {:z 0}}
(roll-out map-of-maps)
(roll-out stop-at? map-of-maps)
Take a map of maps, return sequence of vectors.
How?
(set (roll-out {:a {:b 3 :c 4} :x {:z 0}})) ;; because ordering. => #{[:a :b 3] [:a :c 4] [:x :z 0]} (set (roll-out #(contains? % :b) {:a {:b 3 :c 4} :x {:z 0}})) => #{[:a {:b 3 :c 4}] [:x :z 0]}
Take a map of maps, return sequence of vectors. How? (set (roll-out {:a {:b 3 :c 4} :x {:z 0}})) ;; because ordering. => #{[:a :b 3] [:a :c 4] [:x :z 0]} (set (roll-out #(contains? % :b) {:a {:b 3 :c 4} :x {:z 0}})) => #{[:a {:b 3 :c 4}] [:x :z 0]}
(row-adjuster default-row)
Creates a function that will return vectors of same length as default-row.
Missing columns will be filled by defaults. Extra columns dropped.
Why?
Because *SV does not have to be well formed, numbers of column may vary.
How?
((row-adjuster [1 2 3]) [:x]) => [:x 2 3] ((row-adjuster [1 2 3]) [:1 :2 :3 :4]) => [:1 :2 :3]
Creates a function that will return vectors of same length as default-row. Missing columns will be filled by defaults. Extra columns dropped. Why? Because *SV does not have to be well formed, numbers of column may vary. How? ((row-adjuster [1 2 3]) [:x]) => [:x 2 3] ((row-adjuster [1 2 3]) [:1 :2 :3 :4]) => [:1 :2 :3]
(row-field-unpacker delimiter a-row)
Run field unpacker over entire row.
Why?
Partial it away and apply to nested CSV/TSV stuff.
How?
(row-field-unpacker , ["xnay" "ala,ma,kota" "unpackey") => ["xnay" ["ala" "ma" "kota"] "unpackey"]
Run field unpacker over entire row. Why? Partial it away and apply to nested CSV/TSV stuff. How? (row-field-unpacker \, ["xnay" "ala,ma,kota" "unpackey") => ["xnay" ["ala" "ma" "kota"] "unpackey"]
(vec->map header values)
(vec->map defaults header values)
Takes header and values vector, zipmaps, adds metadata. Allows defaults.
Why?
Singular operation for vecs->maps, with inputs attached as meta.
How? (vec->map [:k1 :k2] [1 2]) => {:k1 1, :k2 2} (vec->map {:kx 100} [:k1 :k2] [1 2]) => {:kx 100, :k1 1, :k2 2} (meta (vec->map {:kx 100} [:k1 :k2] [1 2])) => {:defaults {:kx 100}, :header [:k1 :k2], :values [1 2]}
Takes header and values vector, zipmaps, adds metadata. Allows defaults. Why? Singular operation for vecs->maps, with inputs attached as meta. How? (vec->map [:k1 :k2] [1 2]) => {:k1 1, :k2 2} (vec->map {:kx 100} [:k1 :k2] [1 2]) => {:kx 100, :k1 1, :k2 2} (meta (vec->map {:kx 100} [:k1 :k2] [1 2])) => {:defaults {:kx 100}, :header [:k1 :k2], :values [1 2]}
(vecs->maps a-seq)
(vecs->maps head tails)
(vecs->maps defaults head tails)
Takes header vector and tails, returns seq of maps.
Zipmaps head with tails. Merges with defaults, doing nil substitution.
Why?
Maps are friendlier then vectors.
How?
(vecs->maps [[:k1 :k2] [1 2] [3 4]]) => ({:k1 1, :k2 2}, {:k1 3 :k2 4}) (vecs->maps [:k1 :k2] [[1 2] [3 4]]) => ({:k1 1, :k2 2}, {:k1 3 :k2 4}) (let [s [[:a :b] [1 2] [3 4]]] (vecs->maps (first s) (rest s))) => ({:a 1, :b 2}, {:a 3, :b 4}) (let [d {:x 100, :b 9} s [[:a :b] [1 nil] [3 4]]] (vecs->maps d (first s) (rest s))) => ({:a 1 :b 9 :x 100} {:a 3 :b 4 :x 100})
Takes header vector and tails, returns seq of maps. Zipmaps head with tails. Merges with defaults, doing nil substitution. Why? Maps are friendlier then vectors. How? (vecs->maps [[:k1 :k2] [1 2] [3 4]]) => ({:k1 1, :k2 2}, {:k1 3 :k2 4}) (vecs->maps [:k1 :k2] [[1 2] [3 4]]) => ({:k1 1, :k2 2}, {:k1 3 :k2 4}) (let [s [[:a :b] [1 2] [3 4]]] (vecs->maps (first s) (rest s))) => ({:a 1, :b 2}, {:a 3, :b 4}) (let [d {:x 100, :b 9} s [[:a :b] [1 nil] [3 4]]] (vecs->maps d (first s) (rest s))) => ({:a 1 :b 9 :x 100} {:a 3 :b 4 :x 100})
(vecs-maker)
(vecs-maker defaults)
(vecs-maker defaults header-prep row-prep)
Accepts defaults and two output producing functions of header and row.
By default header-prep is vector of SCREAMING_SNAKE_CASE_STRING.
By default row-prep is a vector of string with nil becoming "NULL".
Bespoke header based on first records, so they better be uniform!
Why?
Quick and dirty dumps!
How? ((vecs-maker) [[:x :y :z] [{:x 0 :y 0} {:x 10 :y 10}]]) => (["X" "Y" "Z"] ["0" "0" "NULL"] ["10" "10" "NULL"]) ((vecs-maker {:z 0}) [[:x :y :z] [{:x 0 :y 0} {:x 10 :y 10}]]) => (["X" "Y" "Z"] ["0" "0" "0"] ["10" "10" "0"]) ((vecs-maker {:z 0} identity identity) [[:x :y :z] [{:x 0 :y 0} {:x 10 :y 10}]]) => ([:x :y :z] [0 0 0] [10 10 0]) ((vecs-maker nil identity identity) [[:x :y :z] [{:x 0 :y 0} {:x 10 :y 10}]]) => ([:x :y :z] [0 0 nil] [10 10 nil])
Accepts defaults and two output producing functions of header and row. By default header-prep is vector of SCREAMING_SNAKE_CASE_STRING. By default row-prep is a vector of string with nil becoming "NULL". Bespoke header based on first records, so they better be uniform! Why? Quick and dirty dumps! How? ((vecs-maker) [[:x :y :z] [{:x 0 :y 0} {:x 10 :y 10}]]) => (["X" "Y" "Z"] ["0" "0" "NULL"] ["10" "10" "NULL"]) ((vecs-maker {:z 0}) [[:x :y :z] [{:x 0 :y 0} {:x 10 :y 10}]]) => (["X" "Y" "Z"] ["0" "0" "0"] ["10" "10" "0"]) ((vecs-maker {:z 0} identity identity) [[:x :y :z] [{:x 0 :y 0} {:x 10 :y 10}]]) => ([:x :y :z] [0 0 0] [10 10 0]) ((vecs-maker nil identity identity) [[:x :y :z] [{:x 0 :y 0} {:x 10 :y 10}]]) => ([:x :y :z] [0 0 nil] [10 10 nil])
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close