在 Clojure 中,vector 是一種有序、可索引、不可變的集合,可包含零個或多個值。這表示向量一旦建立之後就無法修改。用來操作向量的函式會回傳新的向量,而原本的向量保持不變。向量中的值可以是不同的型別。向量可以這樣定義:
(def empty [])
(def single-value [5])
(def single-value-alternative (vector 5))
(def three-values [1 "a" "b"])
我們可以用索引從向量中取出元素。Clojure 向量的索引從零開始,也就是說,第一個元素的索引一律是零:
(def numbers [2 3 5])
;; Read value from vector
(get numbers 2)
;;=> 5
;; Update value in vector
(assoc numbers 2 9)
;;=> [2 3 9]
原本的向量並不會改變:
numbers
;;=> [2 3 5]
若要記住更新後的值,我們需要把它傳遞下去,或是將它存進 var 中:
(def updated-numbers
(assoc numbers 2 9))
(get updated-numbers 2)
;;=> 9
你是個熱衷的賞鳥者,會記錄過去七天裡有多少隻鳥飛進你的花園。
你有六個任務,全都和飛進花園的鳥的數量有關。
為了方便比較,你總會把上週的紀錄放在手邊,那些數字是:0、2、5、3、7、8 和 4。建立一個包含上週紀錄的向量:
last-week
;;=> [0 2 5 3 7 8 4]
實作today函式,回傳今天有多少隻鳥飛進你的花園。鳥的數量依日期排序,第一個元素是最早那天的數量,最後一個元素則是今天的數量。
(def birds-per-day [2 5 0 7 4 1])
(today birds-per-day)
;;=> 1
實作inc-bird函式來增加今天的數量:
(inc-bird birds-per-day)
;;=> [2 5 0 7 4 2]
實作day-without-birds?這個述詞函式;如果有一天沒有任何鳥飛進花園,就回傳true,否則回傳false:
(day-without-birds? birds-per-day)
;;=> true
實作n-days-count函式,回傳從這週開始飛進花園的鳥的數量,但只計算從這週開始算起指定的天數。
(n-days-count birds-per-day 4)
;;=> 14
有些日子比其他日子忙。只要一天有五隻以上的鳥飛進你的花園,就算忙碌的一天。
實作busy-days函式,回傳忙碌的天數:
(busy-days birds-per-day)
;;=> 2
過去一年來,你發現有些星期會形成相同又奇特的模式,數量會在一和零之間交替。實作odd-week?函式,如果這週的鳥數模式符合這個奇數模式,就回傳true:
(odd-week? [1 0 1 0 1 0 1])
;;=> true