Skip to content

Instantly share code, notes, and snippets.

@spariev
Created May 31, 2010 12:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spariev/419810 to your computer and use it in GitHub Desktop.
Save spariev/419810 to your computer and use it in GitHub Desktop.
(use 'clojure.contrib.seq-utils)
(defn- in-range?
[i pair]
(and (>= i (first pair)) (<= i (last pair))))
(defn- glue-pairs
[pairs]
(let [idxs (flatten pairs)
freqs (frequencies idxs)]
(partition-all 2
(filter #(= 1 (freqs %)) idxs))))
(defn- or-clause-from-range
[rng conditions]
(flatten [:or (remove #(= :or %)
(subvec conditions (first rng) (inc (last rng))))]))
(defn extract-or-clauses [conditions]
(let [or-ed-ranges (glue-pairs (->> (indexed conditions)
(filter #(= :or (last %)))
(map first)
(map (fn [i] [(dec i) (inc i)]))))
or-range-for-idx (fn [idx] (first
(filter
(partial in-range? idx) or-ed-ranges)))]
(distinct
(->> (indexed conditions)
(map #(let [or-range (or-range-for-idx (first %))]
(if or-range
(or-clause-from-range or-range conditions) (last %))))))))
;; user> (extract-or-clauses ["foo" "bar" :or "baz" :or "biz" "chunky bacon" "c" :or "l" :or "j" "ohai"])
;; => ("foo" (:or "bar" "baz" "biz") "chunky bacon" (:or "c" "l" "j") "ohai")
@candera
Copy link

candera commented Jun 3, 2010

(defn- in-range?
[i [lower upper]](= lower i upper))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment