January 3, 2021
By: Kevin

总有你不知道的8个/组函数/宏

  1. clojure.set/map-invert 有没有想吧map的key和val倒置过来?
(clojure.set/map-invert {:a 1 :c 2})
  1. clojure.set/projectclojure.set/join 可以实现表连接操作.
(def users
  #{{:user-id 1 :name "john"   :age 22 :type "personal"}
    {:user-id 2 :name "jake"   :age 28 :type "company"}
    {:user-id 3 :name "amanda" :age 63 :type "personal"}})

(def accounts
  #{{:acc-id 1 :user-id 1 :amount 300.45 :type "saving"}
    {:acc-id 2 :user-id 2 :amount 1200.0 :type "saving"}
    {:acc-id 3 :user-id 1 :amount 850.1 :type "debit"}})

(require '[clojure.set :as s])

;; Clojure equivalent of the SQL:
;; SELECT users.user-id, accounts.acc-id,
;;        users.type as type, accounts.type as atype
;; FROM users
;; INNER JOIN accounts ON users.user-id = accounts.user-id;

(s/project
 (s/join users (s/rename accounts {:type :atype}))
 [:user-id :acc-id :type :atype])
  1. some-fn 许多个函数作用于同一个collection, 拿到第一个非false(nil)的结果, 否则返回nil
((some-fn :a :b :c :d) {:c 3 :d 4})
  1. every-pred 多个条件联合过滤的时候特别有用
(filter (every-pred pos? ratio?)
  [0 2/3 -2/3 1/4 -1/10 5 3/3])
  ;; => (2/3 1/4)
  1. bounded-count 做多从一个lazyseq中数出n个
(bounded-count 10000 (range)) ;; 做多数到10000
  1. keep-indexed 处理函数接受两个参数idx 和 val
(keep-indexed #(if (odd? %1) %2) [:a :b :c :d :e])
  1. some/some?/every? 区分一下
;; some 我们应该比较熟悉了
(some even? [1 2 3 5])
;; some? 等价于 not-nil?
(some? [])
;; every? 顾名思义, collection中的每一个都...
(every? #{1 2} [1 2 3])
;; 符合多个predicate
((every-pred string? (comp (partial > 5) count)) "abc")
  1. for可以有多个let, when
(for [a (range 1000)
      :let [b (- 2000 a)]
      :when (< a b)
      :when (contains? (set (range 1000)))])
Tags: clojure