Created
May 6, 2012 20:21
-
-
Save manuelp/2624207 to your computer and use it in GitHub Desktop.
Small exercise on filtering records by a criteria with multiple values in AND.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns filtering.core | |
(:require clojure.set)) | |
(def records [{:id 10 :cat 12 :div 16} | |
{:id 10 :cat 11 :div 15} | |
{:id 11 :cat 12 :div 18} | |
{:id 11 :cat 22 :div 19}]) | |
(defn has-all? [criteria records] | |
(letfn [(take-vals [criteria records] | |
(reduce conj #{} (map (key criteria) records)))] | |
(clojure.set/subset? (val criteria) (take-vals criteria records)))) | |
(defn satisfy? [criteria records-id] | |
(if (has-all? criteria records-id) | |
records-id | |
[])) | |
(defn filter-by-criteria [criteria records] | |
(letfn [(get-id [records] | |
(reduce conj #{} (map :id records))) | |
(take-by-id [id records] | |
(filter #(= (:id %) id) records))] | |
(reduce into | |
(map #(satisfy? (first criteria) (take-by-id % records)) | |
(get-id records))))) | |
;; Esempi | |
(filter-by-criteria {:div #{18 19}} records) | |
(filter-by-criteria {:cat #{12}} records) | |
(filter-by-criteria {:div #{11 12}} records) | |
(defn random-records | |
"Genera molti record per num id." | |
[num molt] | |
(let [take-random (fn [] (inc (rand-int 100)))] | |
(map #(hash-map :id % :cat (take-random) :div (take-random)) | |
(reduce into (map #(repeat molt %) (range num)))))) | |
;; Esempio con timing | |
;(time (filter-by-criteria {:div #{18 19}} (random-records 1000 10))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment