/
misc.cljc
95 lines (84 loc) · 2.33 KB
/
misc.cljc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
(ns com.wsscode.pathom.misc
#?(:clj
(:import
(java.util
UUID))))
#?(:clj (def INCLUDE_SPECS true)
:cljs (goog-define INCLUDE_SPECS true))
(defn pathom-random-uuid []
#?(:clj (UUID/randomUUID)
:cljs (random-uuid)))
(defn distinct-by
"Returns a lazy sequence of the elements of coll, removing any elements that
return duplicate values when passed to a function f."
([f]
(fn [rf]
(let [seen (volatile! #{})]
(fn
([] (rf))
([result] (rf result))
([result x]
(let [fx (f x)]
(if (contains? @seen fx)
result
(do (vswap! seen conj fx)
(rf result x)))))))))
([f coll]
(let [step (fn step [xs seen]
(lazy-seq
((fn [[x :as xs] seen]
(when-let [s (seq xs)]
(let [fx (f x)]
(if (contains? seen fx)
(recur (rest s) seen)
(cons x (step (rest s) (conj seen fx)))))))
xs seen)))]
(step coll #{}))))
(defn dedupe-by
"Returns a lazy sequence removing consecutive duplicates in coll when passed to a function f.
Returns a transducer when no collection is provided."
{:added "1.7"}
([f]
(fn [rf]
(let [pv (volatile! ::none)]
(fn
([] (rf))
([result] (rf result))
([result x]
(let [prior @pv
fx (f x)]
(vreset! pv fx)
(if (= prior fx)
result
(rf result x))))))))
([f coll] (sequence (dedupe-by f) coll)))
(defn index-by
"Like group by, but will keep only the last result."
[f coll]
(reduce
(fn [m x]
(assoc m (f x) x))
{}
coll))
(def sconj (fnil conj #{}))
(def vconj (fnil conj []))
(defn queue
"Create a queue."
([] #?(:clj clojure.lang.PersistentQueue/EMPTY
:cljs cljs.core/PersistentQueue.EMPTY))
([coll]
(reduce conj (queue) coll)))
(defn map-keys
"Map over the given hash-map keys.
Example:
(map-keys #(str/replace (name %) \"_\" \"-\") {\"foo_bar\" 1}) => {\"foo-bar\" 1}
"
[f m]
(into {} (for [[k v] m] [(f k) v])))
(defn map-vals
"Map over the given hash-map vals.
Example:
(map-vals inc {:a 1 :b 2})
"
[f m]
(into {} (for [[k v] m] [k (f v)])))