``````(list 1 2 3)           ;=> (1 2 3)
(seq [1 2 3])          ;=> (1 2 3)

(vector 1 2 3)         ;=> [1 2 3]
(vec  '(1 2 3))        ;=> [1 2 3]

(hash-map :a 1 :b 2)   ;=> {:a 1 :b 2}

(hash-set :a :b :c)    ;=> #{:a :b :c}
(set [:a :b :c])       ;=> #{:a :b :c}

;; converting between the various concrete types
(vec some-map)  ;=>  [[:a 1] [:b 2]]
(set some-map)  ;=> #{[:a 1] [:b 2]}

(apply hash-map [:a 1 :b 2])  ;=> {:a 1 :b 2}
(zipmap [:a :b] [1 2])        ;=> {:a 1 :b 2}

(interleave [:a :b :c] [1 2 3])  ;=> (:a 1 :b 2 :c 3)
(interleave [:a :b :c] [1 2 3] [:X :Y :Z])
;;=> (:a 1 :X :b 2 :Y :c 3 :Z)

(interpose "-" [1 2 3])  ;=> (1 "-" 2 "-" 3)

(map vector [1 2 3] [:a :b :c] '(x y z))
;;=> ([1 :a x] [2 :b y] [3 :c z])

;; You can use strings any place a seq is expected,
;; or else explicitly take a seq of one:
(seq "hello")  ;=> '(\h \e \l \l \o)``````

# 1 Adding and Removing Items

``````(conj some-vec  x)  ; appends  to some-vec
(conj some-list x)  ; prepends to some-list
(conj some-set  x)

(conj some-map [k v])
(assoc some-map k v)``````

## 1.2 Removing an item

``````;; For sequential collections, if you know the index
;; of the item you want to remove:
(concat (take idx coll)
(drop (inc idx) coll))``````

If you know the item you’d like to remove (and you don’t know its index):

``````(def stuff ["abc" "mno" "xyz" "mno" "pdq"])
(def this-one "xyz")

;; If you like, you can *find* the index of `this-one`,
(.indexOf stuff this-one)
;; then remove it as shown previously.

;; Remove all ocurrences of this-one:
(remove #(= % "mno")
stuff)
;;=> ("abc" "xyz" "pdq")

;; Remove one of the ocurrences of this-one:
(defn remove-one
[x coll]
(let [f (first coll)
r (rest coll)]
(if (= f x)
r
(cons f (remove-one x r)))))

(remove-one "mno" stuff)  ;=> ("abc" "xyz" "mno" "pdq")``````

Interesting note pointed out to me by amalloy: functions which operate primarily on sequences should take the data structure argument last; just like how `map`, `filter`, `remove`, `reduce`, etc. do.

To remove a more complex data structure from a sequential collection:

``````(def things [{:name "abc" :num 4}
{:name "mno" :num 7}
{:name "xyz" :num 9}
{:name "mno" :num 3}])

;; If you didn't know what order the items are in,
;; to remove any maps with :name "mno":
(remove #(= (:name x) "mno")
things)

;; If you just want to remove *one* with the name "mno",
;; it's almost the same as shown previously:
(defn remove-one-by-name
[its-name coll]
(let [f (first coll)
r (rest coll)]
(if (= (:name f) its-name)
r
(cons f (remove-one-by-name its-name r)))))

(remove-one-by-name "mno" things)
;;=> ({:name "abc" :num 4}
;;    {:name "xyz" :num 9}
;;    {:name "mno" :num 3})``````

Extra Credit: write your own generic `remove-one` where it takes a predicate as the the first arg!

For maps, use `dissoc` to remove items.

For sets, use `disj`.

# 2 Building up vector values in a hashmap

Although you’ll usually use `group-by` for tasks like this, the following can nevertheless be handy:

``````(update-in {}
[:a]
(fnil conj [])  ; start us off with an empty vec if necessary
"foo")

;;=> {:a ["foo"]}

(def input [[:a "foo"] [:b "bar"] [:a "baz"]])

;; Maybe useful in a `reduce`:
(reduce (fn [accum [k v]]
(update-in accum [k] (fnil conj []) v))
{}
input)

;;=> {:b ["bar"], :a ["foo" "baz"]}

;; Whereas...
(let [stuff (group-by first input)]
;; So, stuff is `{:a [[:a "foo"] [:a "baz"]], :b [[:b "bar"]]}`
(for [[k v] stuff]
[k (map second v)]))
;;=> ([:a ("foo" "baz")] [:b ("bar")])``````

Would have gotten `{:a ("foo")}` if we’d used `conj` instead of `(fnil conj [])`.

# 3 Finding Items

``````;; Given an index:
(nth some-sequential idx)

;; Given the item, you can find the index:
(.indexOf some-sequential x)  ; nil if x isn't in there.

;; See if a set contains an item:
(the-set x)  ; nil if x isn't in the-set.
;; or, if `x` is a keyword:
(:some-kwd the-set)

;; See if a map has an entry for key `:k`:
(the-map :k)
(get the-map :k)  ; same
(:k the-map)``````

Given a sequential collection of maps (an example of one of them might look like `{:name "Foo" :num 4}`), find the one with some particular `:name`:

``````(filter #(= (:name %) "Bar")
[{:name "Foo" :num 4}
{:name "Bar" :num 7}
{:name "Baz" :num 8}])

;; That works if the little maps are in any sort of container.

;; Note though: that gets *all* of the items where "Bar" is the
;; name. If you only want to get *one* where "Bar" is the name, wrap
;; the `filter` with `first`.

;; If you want to find the index of the first one
;; with that name:
(def stuff [{:name "Foo" :num 4}
{:name "Bar" :num 7}
{:name "Baz" :num 8}
{:name "Bar" :num 9}])

;; Well, here's one way that comes to mind.
(defn find-idx-of-one-by-name
[coll its-name]
(.indexOf (map #(= (:name %) its-name)
coll)
true))``````

# 4 Detecting Duplicates

Since you can use `frequencies` to show you how many of each element there is in a collection, just filter out the results which only appear once:

``````(defn dups
"Like `frequencies` but only show entries with a val > 1."
[coll]
(into {} (filter (fn [[k v]] (> v 1))
(frequencies coll))))``````