I have a token scanner that simply returns nil
for characters I'm not interested in. Rather than conj
the nils to my token vector and then later stripping them all out, I want to simply not add them.
I'm using
;; dont conjoin if value false
(defn condj [v val]
(cond-> v, val (conj val)))
to do this. Is there a specific operator or a more concise implementation?
I like the cond->
version and often use that to avoid repetition in the if
version. Don't forget to be explicit about false
values, though. I also like to use Plumatic Schema to be explicit about the data shape entering and leaving the function:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[schema.core :as s]))
(s/defn condj :- [s/Any]
"Conjoin an item onto a vector of results if the item is not nil."
[accum :- [s/Any]
item :- s/Any]
(cond-> accum
(not (nil? item)) (conj item)))
(dotest
(let [result (-> []
(condj :a)
(condj :2)
(condj false)
(condj "four")
(condj nil)
(condj "last"))]
; nil is filtered but false is retained
(is= result [:a :2 false "four" "last"])))
You may also be interested in another version using my favorite library:
(s/defn condj :- [s/Any]
"Conjoin an item onto a vector of results if the item is not nil."
[accum :- [s/Any]
item :- s/Any]
(cond-it-> accum
(not-nil? item) (append it item)))
For more complicated forms, using the placeholder symbol it
makes it explicit where the value is being threaded. I also like the convenience functions not-nil?
and append
since they also make the intent of the code plainer.