映射

映射 在 Common Lisp

12 個練習

關於 映射

映射指的是把一個函式套用到序列中的每個元素,藉此產生一個新的序列。

mapcar可以用來把函式映射到一個裝著物件的陣列上

(mapcar #'double '(1 2 3 4)) ; => (2 4 6 8)

注意,第一個引數是要呼叫的函式。 #'是一種特殊的引用語法,用來指定函式。 (這裡也可以寫成'double,但使用#'是慣用寫法,而且可以說「更正確」。)

不只一個陣列

映射不限定只能把函式套用到單一序列,也可以用在多個序列上。 如果提供了N個序列,函式就必須接受N個引數。

(mapcar #'list '(1 2) '(a b) '("foo" "bar")) ; => ((1 a "foo") (2 b "bar"))

其他的 map 函式

除了mapcar之外,還有其他可以對陣列做映射的函式。 mapcar無疑是最常用的,但認識其他函式也很有幫助。

maplist的運作方式類似mapcar,但它處理的是連續的子陣列,而不是個別元素。 首先處理整個陣列,接著處理它的cdr,再處理那個cdr的cdr,依此類推:

(maplist #'identity '(a b c)) ; => ((A B C) (B C) (C))

mapc和mapl分別類似mapcar和maplist,但它們不會收集結果,而是回傳第一個陣列。 這適合用在帶有副作用的操作上。

mapcan和mapcon類似mapcar和maplist,但結果會透過nconc攤平。nconc類似append,不過除了最後一個引數之外,它會破壞其他所有引數。

在其他序列上映射

映射不只能用在陣列上。任何序列(另一個概念會介紹)都可以映射。 如果序列不是陣列,就要使用map函式。

map接受 3 個以上的引數:

  • 第一個是結果序列的型別
  • 第二個是要套用的函式
  • 第三個以及剩下的引數,是要處理的序列。
(map 'list #'double '(1 2 3))        ; => (2 4 6)
(map 'string #'char-upcase "foobar") ; => "FOOBAR"

特殊情況是,如果結果序列的型別指定為nil,就會回傳nil。 這種用法(就像上面的mapc和mapl)是用來產生副作用的。

透過 GitHub 編輯 連結會在新視窗或分頁中開啟

學習 映射

練習已鎖定

再解鎖 8 個練習,就能練習 映射