我們使用的程式語言叫做 Lisp,這個名字是 LIST Processing 的縮寫,所以你可能會猜想這門語言具備處理項目陣列的能力。沒錯,你說對了!
雖然 Common Lisp 有陣列以外的其他資料結構,但陣列依然被大量使用。
在 Common Lisp 中,陣列是一連串的項目。它也被稱為 cons(大多是基於歷史因素)。這些項目本身不一定要是相同的型別。例如,你可以有一個包含1、two、"III"的陣列。
你可以直接輸入像這樣帶引號的陣列:'(1 two "III"),這樣就會建立並求值一個陣列(它會求值成 (1 two "III"))。
還有兩個用來建立陣列的主要函式:list 和 cons。
list 接受零個或多個引數,並求值成一個用這些值建立起來的陣列:
(list 1 'two "III") ; => (1 two "III")
cons 接受兩個項目,並建立一個陣列,把第一個項目當作它的 car(陣列的開頭),第二個項目當作它的 cdr(陣列的其餘部分):
(cons 1 2) ; => (1 . 2) ;; (a list without `nil` as its `cdr` is printed in this way)
(cons 1 nil) ; => (1)
(cons 1 (cons 2 nil)) ; => (1 2)
函式 car 和 cdr 可以用來存取陣列的 car 和 cdr。
(first 和 rest 是 car 和 cdr 的同義詞,運作方式完全相同。)
陣列的長度可以用 length 取得。空陣列的長度是零。
任意項目都可以用 nth 存取(請注意,陣列的索引從 0 開始)。
要求超出陣列長度的索引,並_不_算錯誤。它會求值成 nil:
(nth 23 '(short list)) ; => nil
還有幾個用來存取陣列開頭項目的輔助方法:first、second、third,一路到 tenth。很方便吧?
兩個或多個陣列可以用 append 合併:
(append '(a b c) '(1 2 3)) ; => (A B C 1 2 3)
(append '(a b c) '()) ; => (A B C)
傳給 append 的每個引數都必須是陣列。
Lisp 外星人 Leslie 需要去買點東西。有一份購物清單是很重要的,要能往裡面加東西,也要能從裡面拿掉東西。
當然,單純的紙筆對 Lisp 外星人來說是不夠的。「List」幾乎就是「Lisp」這個字的全部了!一定得寫些函式來幫忙記錄要買的東西。
你能幫 Leslie 記錄這份購物清單嗎?
首先,Leslie 需要建立一個空的清單。一個叫做new-list的函式正好適合這件事。
(new-list) ; => ()
喔不……Leslie 心裡已經有幾樣想買的東西了,所以他們需要一個函式,接受三個項目(還好 Leslie 只會建立包含三個項目的清單,不多也不少!),並用這些東西建立一份新的購物清單。寫一個list-of-things函式,接受三個項目並回傳包含它們的清單。
(list-of-things 'bread 'milk 'butter) ; => '(bread milk butter)
去商店之前,Leslie 會先翻翻儲藏室,看看自己需要什麼。幫他們寫一個add-to-list函式,把項目加到清單的開頭。
(add-to-list 'butter '(bread)) ; => '(butter bread)
購物時,Leslie 想知道接下來要找什麼。他們也喜歡先偷看清單,看看第二個、第三個,甚至是第 23 個項目(他們的幸運數字)。
first-thing會求值為清單上的第一樣東西second-thing會求值為第二樣東西third-thing會求值為第三樣東西twenty-third-thing會求值為第二十三樣東西(first-thing '(bread butter milk)) ; => 'bread
(second-thing '(bread butter milk)) ; => 'butter
(third-thing '(bread butter milk)) ; => 'milk
Leslie 想找出清單上的第一個項目,並把它從架上拿下來。幫他們寫一個remove-first-item函式,它會求值為輸入清單中除了第一個項目以外的所有項目。
(remove-first-item '(bread butter milk)) ; => '(butter milk)
Leslie 發現自己不小心做了兩份購物清單,而不是一份!寫一個list-append函式,回傳一個清單,其中包含第一個清單的元素,後面接著第二個清單的元素。
(list-append '(bread salt) '(butter milk)) ; => '(bread salt butter milk)
Leslie 開始擔心這趟購物會花上好一陣子。這份清單上到底有幾樣東西?寫一個just-how-long函式,告訴他們清單有多長。
(just-how-long '(bread milk butter salt)) ; => 4