I am trying to replace duplicates in a vector with empty strings. However, the only functions I can find are to remove duplicates, not replace them. How can I take
["Oct 2016" "Oct 2016" "Nov 2016" "Nov 2016" "Nov 2016" "Nov 2016"]
and output:
["Oct 2016" "" "Nov 2016" "" "" ""]
Everything I can find will return ["Oct 2016" "Nov 2016"] I'm currently achieving the desired output by doing a nested doseq, but it seems inefficient. Is there a better way to achieve this?
Thanks!
Here is a strategy for a solution.
loop over the items of the vector.set of visited items. It can be used to check for uniqueness."" into the result vector.Code:
(defn duplicate->empty [xs]
(loop [xs (seq xs)
result []
found #{}]
(if-let [[x & xs] (seq xs)]
(if (contains? found x)
(recur xs (conj result "") found)
(recur xs (conj result x) (conj found x)))
result)))
Calling it:
(duplicate->empty ["Oct 2016" "Oct 2016" "Nov 2016" "Nov 2016" "Nov 2016" "Nov 2016"])
=> ["Oct 2016" "" "Nov 2016" "" "" ""]
Transducer version just for completeness.
(defn empty-duplicates
([]
(fn [rf]
(let [seen (volatile! #{})]
(fn
([] (rf))
([res] (rf res))
([res x]
(if (contains? @seen x)
(rf res "")
(do (vswap! seen conj x)
(rf res x))))))))
([coll]
(sequence (empty-duplicates) coll)))
(comment
(def months ["Oct 2016" "Oct 2016" "Nov 2016" "Nov 2016" "Nov 2016" "Nov 2016"])
(into [] (empty-duplicates) months) ;=> ["Oct 2016" "" "Nov 2016" "" "" ""]
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With