関数 lambdaを使うと、一連の流れをひとまとめにして、apply、mapcarなどに渡す引用関数として1回だけ使う仮の自作関数を作ることができます。
今回はmapcarとlambdaを関数foreachのように使う例です。
予備知識
自作関数について。
mapcar は、リストの値を処理して結果をリストで戻す関数です。
foreachについて。
foreachはリストにした値を使って順番に処理する関数です。
自作関数 を定義して繰り返す
このような作図をするコマンドを例に説明していきます。
自作関数を関数内で定義した場合です。
(defun c:test1 (/ Example Pt1)
(setq Pt1 (getpoint))
(defun Example (Ang / Pt2)
(setq Pt2 (polar Pt1 (/ (* Ang pi) 180) 50))
(command-s "._LINE" Pt1 Pt2 "")
(command-s "._CIRCLE" Pt2 10)
)
(Example 0)
(Example 30)
(Example 60)
(Example 90)
(princ))
定義した関数Exampleに必要な引数は数値Angで、
「点Pt1から角度Angに長さ50の線分を引いて端っこに半径10の円を描く。」
という機能があります。
Pt1の点座標をgetpointで得た後に、 (Example 0) と、関数Exampleに角度0を渡すと以下のような図が作図されます。
さらに、(Example 30) (Example 60) (Example 90)と角度に違う値を入れて繰り返すと例の作図が仕上がります。
関数 foreach
関数foreachを使うと、角度の部分をリストにして、同じ処理を繰り返すことができます。
引数として、角度Angの値のリスト、上の例では自作関数Exampleとして定義した処理を渡します。
(defun c:test2 (/ Pt1 Pt2 Ang)
(setq Pt1 (getpoint))
(foreach Ang (list 0 30 60 90)
(setq Pt2 (polar Pt1 (/ (* Ang pi) 180) 50))
(command-s "._LINE" Pt1 Pt2 "")
(command-s "._CIRCLE" Pt2 10)
)
(princ))
関数 mapcar
関数mapcarを使うと、引用関数で使う引数をリストで一気に渡して処理できます。
test1では
(Example 0)
(Example 30)
(Example 60)
(Example 90)
引数の角度の値を変更ながら4回Exampleを繰り返して例の図を作図しました。
mapcarの場合、引用関数としてExampleを指定し、Exampleに必要な引数Angの値をリストで渡すと、そのリストに入れた値の数だけ繰り返されます。
(mapcar (quote Example) (list 0 30 60 90))
これで、リストの4つの値をひとつづつ引数にしてExampleで繰り返すので、test1と同じ働きになります。
さらに、quote list を省略すると、
(mapcar ‘Example ‘(0 30 60 90))
になります。
(defun c:test3 (/ Example Pt1)
(setq Pt1 (getpoint))
(defun Example (Ang / Pt2)
(setq Pt2 (polar Pt1 (/ (* Ang pi) 180) 50))
(command-s "._LINE" Pt1 Pt2 "")
(command-s "._CIRCLE" Pt2 10)
)
(mapcar ‘Example ‘(0 30 60 90))
(princ))
関数 lambda
関数 lambdaを使うと、mapcarの引用関数として1回だけ使う仮の関数を定義することができます。
コマンドtest3ではmapcarを使って、自作関数Exampleにリストで4つ値を渡して繰り返しました。
(mapcar (quote Example) (list 0 30 60 90)
このExampleを、lambdaとコードに書き換えて仮の自作関数として使います。
(defun c:test4 (/ Pt1 Pt2)
(setq Pt1 (getpoint))
(mapcar
(quote (lambda (Ang)
(setq Pt2 (polar Pt1 (/ (* Ang pi) 180) 50))
(command-s "._LINE" Pt1 Pt2 "")
(command-s "._CIRCLE" Pt2 10)
))
(list 0 30 60 90)
)
(princ))
quote とlistを ‘ で省略した場合です。
(defun c:test5 (/ Pt1 Pt2)
(setq Pt1 (getpoint))
(mapcar
'(lambda (Ang)
(setq Pt2 (polar Pt1 (/ (* Ang pi) 180) 50))
(command-s "._LINE" Pt1 Pt2 "")
(command-s "._CIRCLE" Pt2 10)
)
'(0 30 60 90)
)
(princ))
自分がわかりやすい書き方を使えばいいと思います。
でも、いろんな書き方を知っておくと、誰かが作ったAutoLISPを解読するときに役に立ちます。
まとめ
- 関数 lambdaを使うと引用関数として1度だけ使える仮の自作関数を定義することができる。
- 関数 lambdaと関数mapcarで、関数foreachみたいに使える。
- 2つ以上の値リストを使いたいときはforeachよりもmapcar & lambdaが便利。
関連記事
mapcar について。
foreach について
自作関数について
コマンド関数内で一時的な自作関数、mapcar / lambdaを使った作図コマンドのサンプルです。
Comments