
;;;; Data Structures

  > So far , we 've dealt with discrete pieces of data : one number , one
  string , one value . When programming , it is more often the case that
;; you want to work with groups of data.

;; > Clojure has great facilities for working with these groups, or
  * collections * , of data . Not only does it provide four different types
;; of collections, but it also provides a uniform way to use all of these
;; collections together.

;; Vectors

;; > A vector is a sequential collection of values. A vector may be
;; > empty. A vector may contain values of different types.
;; > Each value in a vector is numbered starting at 0, that number is
;; > called its index. The index is used to refer to each value when
;; > looking them up.

;; > To imagine a vector, imagine a box split into some number of
;; > equally-sized compartments. Each of those compartments has a number.
;; > You can put a piece of data inside each compartment and always know
;; > where to find it, as it has a number.


;; > Note that the numbers start with 0. That may seem strange, but we
  > often count from zero when programming .

;; FIXME IMAGE
;;; ![Vector](img/vector.png)

;; >Vectors are written using square brackets with any number of pieces
;; >of data inside them, separated by spaces. Here are some examples of
;; >vectors:

[1 2 3 4 5]
[56.9 60.2 61.8 63.1 54.3 66.4 66.5 68.1 70.2 69.2 63.1 57.1]
[]

;; Creation

;; > Instead of writing a vector with square brackets, you can also use the vector
;; > function to create a vector. All arguments are collected and placed inside a new
;; > vector.

(vector 5 10 15)

;; > `conj` takes a vector and some other values, and returns a new vector with the
  > extra value added . `  ` is short for conjoin , which means to join or combine .
;; > This is what we're doing: we're joining the extra value to the vector. `conj`
;; > can be used with any kind of collection. Right now the only kind of
;; > collection we've encountered is a vector.

(conj [5 10] 15)

;; Extraction

  > Now , take a look at these four functions . ` count ` gives us a
;; count of the number of items in a vector. `nth` gives us the nth
;; item in the vector. Note that we start counting at 0, so in the
  example , calling ` nth ` with the number 1 gives us what we 'd call the
  second element when we are n't programming . ` first ` returns the first
  item in the collection . ` rest ` returns all except the first item .
;; Try not to think about that and `nth` at the same time, as they can
;; be confusing.

(count [5 10 15])

(nth [5 10 15] 1)

(first [5 10 15])

(rest [5 10 15])


;;;; EXERCISE: Make a vector

  Make a vector of the high temperatures for the next 7 days in the
;; town where you live.  Then use the `nth` function to get the high
  temperature for next Tuesday .


;;;; Maps

;; >Maps hold a set of keys and values associated with them. You can
;; >think of it like a dictionary: you look up things using a word (a
;; >keyword) and see the definition (its value). If you've programmed in
;; >another language, you might have seen something like maps--maybe
;; >called dictionaries, hashes, or associative arrays.

;; FIXME ![Map](img/map.png)

;; > We write maps by enclosing alternating keys and values in curly braces, like so.

;; > Maps are useful because they can hold data in a way we normally
  > think about it . Take our made up example ,   . A map can
  > hold her first name and last name , her address , her favorite food ,
;; > or anything else. It's a simple way to collect that data and make it
;; > easy to look up. The last example is an empty map. It is a map that
;; > is ready to hold some things, but doesn't have anything in it yet.

  { : first "  " : last "  " }
  { : a 1 : b " two " }
;; {}

  > ` assoc ` and ` dissoc ` are paired functions : they associate and disassociate items from a map . See how we add the last name "  " to the map with ` assoc ` , and then we remove it with ` dissoc ` . ` merge ` merges two maps together to make a new map .

(assoc {:first "Sally"} :last "Brown")

(dissoc {:first "Sally" :last "Brown"} :last)

(merge {:first "Sally"} {:last "Brown"})

;; > `count` every collection has this function. Why do you think the
  > answer is two ? ` count ` is returning the number of associations .

;; > Since map is a key-value pair, the key is used to get a value from a
  > map . One of the ways often used in Clojure is the examples below .
;; > We can use a keyword like using a function in order to look
  > up values in a map . In the last example , we supplied the key ` :  ` .
;; > This works when the key we asked for is not in the map.

(count {:first "Sally" :last "Brown"})

(get {:first "Sally" :last "Brown"} :first)

(get {:first "Sally"} :last)

(get {:first "Sally"} :last :MISS)

;; > Then we have `keys` and `vals`, which are pretty simple: they return
;; > the keys and values in the map. The order is not guaranteed, so we
  > could have gotten ` (: first : last ) ` or ` (: last : first ) ` .

(keys {:first "Sally" :last "Brown"})

(vals {:first "Sally" :last "Brown"})

;; > After the creation, we want to save a new value associated to the
;; > key. The `assoc` function can be used by assigning a new value to
;; > the existing key.
;; > Also, there's handy function `update`. The function takes map and
  > a key with a function . The value of specified key will be the first
;; > argument of the given function.
;; > The `update-in` function works like `update`, but takes a vector of keys
;; > to update at a path to a nested map.

(def hello {:count 1 :words "hello"})

(update hello :count inc)

(update hello :words str ", world")


(def mine {:pet {:age 5 :name "able"}})

(update-in mine [:pet :age] - 3)


;; Collections of Collections

;; > Simple values such as numbers, keywords, and strings are not the
;; > only types of things you can put into collections. You can also put
;; > other collections into collections, so you can have a vector of
;; > maps, or a list of vectors, or whatever combination fits your data.

;; Vector of Maps

(def characters
  [{:name "Snoopy"
    :species "dog"}
   {:name "Woodstock"
    :species "bird"}
   {:name "Charlie Brown"
    :species "human"}])

(:name (first characters))

(map :name characters)


;; EXERCISE: Modeling Yourself

;; * Make a map representing yourself
  * Make sure it contains your first name and last name
;; * Then, add your hometown to the map using [assoc](/) or [merge](/).

;; EXERCISE [BONUS]: Modeling your classmates

  * First , take the map you made about yourself in previous exercise .
  * Then , create a vector of maps containing the first name , last name and hometown of two or three other classmates around you .
  * Lastly , add your map to their information using [ conj]( / clojure.core / conj ) .

 Data Structures
 you want to work with groups of data.
 > Clojure has great facilities for working with these groups, or
 of collections, but it also provides a uniform way to use all of these
 collections together.
 Vectors
 > A vector is a sequential collection of values. A vector may be
 > empty. A vector may contain values of different types.
 > Each value in a vector is numbered starting at 0, that number is
 > called its index. The index is used to refer to each value when
 > looking them up.
 > To imagine a vector, imagine a box split into some number of
 > equally-sized compartments. Each of those compartments has a number.
 > You can put a piece of data inside each compartment and always know
 > where to find it, as it has a number.
 > Note that the numbers start with 0. That may seem strange, but we
 FIXME IMAGE
 ![Vector](img/vector.png)
 >Vectors are written using square brackets with any number of pieces
 >of data inside them, separated by spaces. Here are some examples of
 >vectors:
 Creation
 > Instead of writing a vector with square brackets, you can also use the vector
 > function to create a vector. All arguments are collected and placed inside a new
 > vector.
 > `conj` takes a vector and some other values, and returns a new vector with the
 > This is what we're doing: we're joining the extra value to the vector. `conj`
 > can be used with any kind of collection. Right now the only kind of
 > collection we've encountered is a vector.
 Extraction
 count of the number of items in a vector. `nth` gives us the nth
 item in the vector. Note that we start counting at 0, so in the
 Try not to think about that and `nth` at the same time, as they can
 be confusing.
 EXERCISE: Make a vector
 town where you live.  Then use the `nth` function to get the high
 Maps
 >Maps hold a set of keys and values associated with them. You can
 >think of it like a dictionary: you look up things using a word (a
 >keyword) and see the definition (its value). If you've programmed in
 >another language, you might have seen something like maps--maybe
 >called dictionaries, hashes, or associative arrays.
 FIXME ![Map](img/map.png)
 > We write maps by enclosing alternating keys and values in curly braces, like so.
 > Maps are useful because they can hold data in a way we normally
 > or anything else. It's a simple way to collect that data and make it
 > easy to look up. The last example is an empty map. It is a map that
 > is ready to hold some things, but doesn't have anything in it yet.
 {}
 > `count` every collection has this function. Why do you think the
 > Since map is a key-value pair, the key is used to get a value from a
 > We can use a keyword like using a function in order to look
 > This works when the key we asked for is not in the map.
 > Then we have `keys` and `vals`, which are pretty simple: they return
 > the keys and values in the map. The order is not guaranteed, so we
 > After the creation, we want to save a new value associated to the
 > key. The `assoc` function can be used by assigning a new value to
 > the existing key.
 > Also, there's handy function `update`. The function takes map and
 > argument of the given function.
 > The `update-in` function works like `update`, but takes a vector of keys
 > to update at a path to a nested map.
 Collections of Collections
 > Simple values such as numbers, keywords, and strings are not the
 > only types of things you can put into collections. You can also put
 > other collections into collections, so you can have a vector of
 > maps, or a list of vectors, or whatever combination fits your data.
 Vector of Maps
 EXERCISE: Modeling Yourself
 * Make a map representing yourself
 * Then, add your hometown to the map using [assoc](/) or [merge](/).
 EXERCISE [BONUS]: Modeling your classmates


  > So far , we 've dealt with discrete pieces of data : one number , one
  string , one value . When programming , it is more often the case that

  * collections * , of data . Not only does it provide four different types





  > often count from zero when programming .



[1 2 3 4 5]
[56.9 60.2 61.8 63.1 54.3 66.4 66.5 68.1 70.2 69.2 63.1 57.1]
[]



(vector 5 10 15)

  > extra value added . `  ` is short for conjoin , which means to join or combine .

(conj [5 10] 15)


  > Now , take a look at these four functions . ` count ` gives us a
  example , calling ` nth ` with the number 1 gives us what we 'd call the
  second element when we are n't programming . ` first ` returns the first
  item in the collection . ` rest ` returns all except the first item .

(count [5 10 15])

(nth [5 10 15] 1)

(first [5 10 15])

(rest [5 10 15])



  Make a vector of the high temperatures for the next 7 days in the
  temperature for next Tuesday .






  > think about it . Take our made up example ,   . A map can
  > hold her first name and last name , her address , her favorite food ,

  { : first "  " : last "  " }
  { : a 1 : b " two " }

  > ` assoc ` and ` dissoc ` are paired functions : they associate and disassociate items from a map . See how we add the last name "  " to the map with ` assoc ` , and then we remove it with ` dissoc ` . ` merge ` merges two maps together to make a new map .

(assoc {:first "Sally"} :last "Brown")

(dissoc {:first "Sally" :last "Brown"} :last)

(merge {:first "Sally"} {:last "Brown"})

  > answer is two ? ` count ` is returning the number of associations .

  > map . One of the ways often used in Clojure is the examples below .
  > up values in a map . In the last example , we supplied the key ` :  ` .

(count {:first "Sally" :last "Brown"})

(get {:first "Sally" :last "Brown"} :first)

(get {:first "Sally"} :last)

(get {:first "Sally"} :last :MISS)

  > could have gotten ` (: first : last ) ` or ` (: last : first ) ` .

(keys {:first "Sally" :last "Brown"})

(vals {:first "Sally" :last "Brown"})

  > a key with a function . The value of specified key will be the first

(def hello {:count 1 :words "hello"})

(update hello :count inc)

(update hello :words str ", world")


(def mine {:pet {:age 5 :name "able"}})

(update-in mine [:pet :age] - 3)





(def characters
  [{:name "Snoopy"
    :species "dog"}
   {:name "Woodstock"
    :species "bird"}
   {:name "Charlie Brown"
    :species "human"}])

(:name (first characters))

(map :name characters)



  * Make sure it contains your first name and last name


  * First , take the map you made about yourself in previous exercise .
  * Then , create a vector of maps containing the first name , last name and hometown of two or three other classmates around you .
  * Lastly , add your map to their information using [ conj]( / clojure.core / conj ) .
