マッピングとは、関数をシーケンスの各要素に適用して、新しいシーケンスを作ることです。
これはmapcar関数を使えば、配列に対して簡単に行えます。
引数を2倍するdoubleという関数があるとしましょう。
(mapcar #'double '(1 2 3 4)) ; => (2 4 6 8)
最初の引数は呼び出す関数であることに注目してください。#'は関数を指定するための特別なクォート構文です。
doubleはまず最初の要素で呼び出され、次に2番目の要素で呼び出され、というふうに進みます。
結果は配列にまとめられ、それがこの式が評価される値になります。
フィルタリングとは、あるシーケンスから、特定の要素以外をすべてコピーして新しいシーケンスを作る処理です。 新しいシーケンスにどの要素を含めるかは、述語関数(真偽値に評価される関数)で決めることも、特定のオブジェクトとの等価性で決めることもできます。
remove-ifは、述語関数とシーケンスを引数に取り、述語が偽の値に評価された要素だけからなるシーケンスを返す関数です。
言い換えると、述語が真に評価される要素をすべて「取り除き」ます。ただし、この関数は元のシーケンスを変更しないことに注意してください!
代わりに、該当する要素を取り除いた新しいシーケンスを返します。すべての値で述語が真だった場合は、空のシーケンスが返されます。
(remove-if #'evenp '(1 2 3 4 5)) ; => (1 3 5)
(remove-if #'oddp '(1 3 5)) ; => ()
シーケンスから特定の要素を削除したい場合は、削除する要素とシーケンスを取るremoveを使います。
シーケンスの中で、削除する要素と等しくない値がすべて返されます。
注意:等価性の判定には、デフォルトでeqlという汎用的な等価性の述語が使われます。
(remove 1 '(1 2 1 3 1 4)) ; => (2 3 4)
(remove #\l "hello") ; => "heo"
Lisp星人のルーシーは数値が好きで、その中には「素晴らしい」ものもあると思っています。
ルーシーは、数値をより素晴らしくする関数を書くのを手伝ってほしいと頼んできました。
ルーシーがどの数値を素晴らしいと考えるかは変わることもあるので、関数は柔軟である必要があります。
数値の配列を、より素晴らしい数値の配列にするには、make-magnificent-maybeという関数を書く必要があります。この関数は、数値に適用する関数と、数値の配列を入力として受け取ります。
(与えられた関数に従って)より素晴らしい数値の配列に評価されるようにしましょう。
(make-magnificent-maybe #'square '(1 2 3)) ; => (1 4 9)
(make-magnificent-maybe #'1+ '(1 2 3)) ; => (2 3 4)
(うまくいけば)数値をより素晴らしくしたあと、ルーシーは本当に素晴らしい数値だけを見たがっています。
1は決して素晴らしくないと確信しているので、それは取り除く必要があります。
しかしそれ以外については、ルーシーは気が変わることもあるので、ここでも数値が素晴らしいかどうかを教えてくれる関数を渡してくれます。
only-the-bestという関数を書く必要があります。この関数は関数と数値の配列を入力として受け取り、最高の数値だけを返します(1と、与えられた関数が真になる数値は除きます)。
(only-the-best #'evenp '(1 2 3 4 5)) ; => (3 5)
(only-the-best #'oddp '(1 3 5)) ; => ()
Exercismに登録すれば、27個のコンセプト92個の演習、そして本物の人間によるメンタリングとともに、Common Lispを学んでマスターできます。すべて無料です。