As it turns out the two functions, fn-apply-cmp-vals and apply-cmp-vals can be replaced by map as
(defn apply-cmp-vals [cmp-vec cmp-vals cmp-vec-idx] (map #(ret-non-match-rows cmp-vec cmp-vec-idx %1) cmp-vals))
Here is some data.
(def v1 [[44 2 3 4 5][1 6 7 5 10][11 12 13 14 15]] (def v2 [[1 2 3 4 44][1 6 7 5 1][11 12 13 14 44]]
The real data is more complicated, mixed numbers and strings, like last name, ssn, and so on, but this data will work as an example.
I want to compare values in a column — column 0 — of v1 with the values of a column in v2, column 4 . And here is what I have come up with, and I’m sure with pure sequences there is probably a cleaner way.
This function accepts a sequence of sequences, s-o-s, a column (index) in s-o-s, and a single comparison value.
(defn ret-non-match-rows "Expects a sequence of sequences, like what is returned from clojure-csv. Returns all csv rows that do not match cmp-val at cmp-col-idx." [s-o-s cmp-col-idx cmp-val] (filter (complement nil?) (map #(if (ret-col-match %1 cmp-val cmp-col-idx) nil %1) s-o-s) ))
That is nice, but what if I want to compare many values? Well, good old
came to the rescue.
(defn fn-apply-cmp-vals [fn cmp-sos cmp-idx] (partial fn cmp-sos cmp-idx)) (defn apply-cmp-vals [cmp-vec cmp-vals cmp-vec-idx] (let [fn-cmp (fn-apply-cmp-vals ret-non-match-rows cmp-vec cmp-vec-idx)] (map #(fn-cmp %1) cmp-vals)))
To test it:
(apply-cmp-vals v2 (map #(nth %1 0 nil) v1) 4) (() () ())
I recently received an interesting comment on stackoverflow. It basically said to give up on indices as much as possible to achieve a functional programming solution, so that is what moved me to seek out a sequence solution instead of trying to locate row numbers where a match occurred. I believe I achieved that goal.