Skip to content

Instantly share code, notes, and snippets.

@j201
Created November 8, 2013 03:05
Show Gist options
  • Save j201/7365644 to your computer and use it in GitHub Desktop.
Save j201/7365644 to your computer and use it in GitHub Desktop.
Simple bag operations for Clojure.
; Clojure doesn't have bags (multi-sets) natively.
; Here are a few utility functions that let you use maps as bags
(defn bag-conj
"Adds an item to a bag"
([bag item]
(if-let [n (get bag item)]
(assoc bag item (inc n))
(assoc bag item 1)))
([bag item & items]
(if items
(recur (bag-conj bag item) (first items) (next items))
(bag-conj bag item))))
(defn bag-disj
"Removes an item from a bag if present"
([bag item]
(if-let [n (get bag item)]
(if (<= n 1)
(dissoc bag item)
(assoc bag item (dec n)))
bag))
([bag item & items]
(if items
(recur (bag-disj bag item) (first items) (next items))
(bag-disj bag item))))
(defn bag
"Creates a bag with the given items"
[& items]
(apply bag-conj {} items))
; And use normal map operations for the rest:
; (def my-bag (bag 1 1 1 2 3 8))
; (my-bag 1) => 3 (the number of times 1 is in the bag)
; (my-bag 4) => nil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment