読者です 読者をやめる 読者になる 読者になる

by shigemk2

当面は技術的なことしか書かない

loop2

Emacs Lisp
(loop for x in '(1 2 3) collect (list x (* x x))) ; => ((1 1) (2 4) (3 9))
(loop for x in '(1 2 3) append (list x (* x x))) ; => (1 1 2 4 3 9)

;; 1から10までの総和を得る
(loop for i from 1 to 10 sum i)		; => 55
;; 1から10までの二乗和を得る
(loop for i from 1 to 10 sum (* i i))	; => 385
;; 二次関数 y = x^2-2x+2の最大値と最小値を求める
(defun y (x) (+ (* x x) (* -2 x) 2))	; => y
;; 0から4までのy(x)の値を求める
(loop for x from 0 to 4 collect (y x))	; => (2 1 2 5 10)
;; 最大値と最小値を求める
(loop for x from 0 to 4 maximize (y x))	; => 10
(loop for x from 0 to 4 minimize (y x))	; => 1

;; countは条件を満たした回数を数える
;; 全要素が奇数のときにt
(loop for x in '(1 3 5) always (oddp x)) ; => t
(loop for x in '(1 2 5) always (oddp x)) ; => nil
;; 全要素が偶数でない (奇数)のときにt
(loop for x in '(1 3 5) never (evenp x)) ; => t
(loop for x in '(1 2 5) never (evenp x)) ; => nil
;; どれかの要素が偶数のときにt
(loop for x in '(1 3 5) thereis (evenp x)) ; => nil
(loop for x in '(1 2 5) thereis (evenp x)) ; => t
;; 奇数の数を数える
(loop for x in '(1 2 5) count (oddp x)) ; => 2

;; 通常のケースはテストの後でdoが実行される
(with-output-to-string
  (loop for i from 1 to 2
	do (princ i)))			; => "12"
;; テストが後なのでdoが先に実行され、iが後退する
(with-output-to-string
  (loop do (princ i)
	for i from 1 to 2))		; => "123"
(with-output-to-string
  (loop do (princ "X")
	for i from 1 to 3
	do (princ i)))			; => "X1X2X3X"

;; 複数ループ
(loop for i from 1 to 3
      for j from 6 to 8
      collect (list i j))		; => ((1 6) (2 7) (3 8))
;; 先に打ち止めになるほうに合わせることもできる
(loop for i from 1 to 3
      for j from 6 to 6
      collect (list i j))		; => ((1 6))
;; 有限ループの繰り返し節がある場合は無限ループがあってもいい
(loop for i from 1 to 3
      for j from 6
      collect (list i j))		; => ((1 6) (2 7) (3 8))
;; 並列ループではなくループを入れ子にする場合
(loop for i from 1 to 3 collect
      (loop for j from 5 to 6
	    collect (list i j)))	; => (((1 5) (1 6)) ((2 5) (2 6)) ((3 5) (3 6)))
(loop for i from 1 to 3 append
      (loop for j from 5 to 6
	    collect (list i j)))	; => ((1 5) (1 6) (2 5) (2 6) (3 5) (3 6))
(loop for i from 1 to 3 collect
      (loop for j from 5 to 6
	    append (list i j)))	; => ((1 5 1 6) (2 5 2 6) (3 5 3 6))

;; ローカル変数を作成する
(loop with a = 2
      for x from 1 to 3
      collect (* x a))			; => (2 4 6)

;; 最後にwithを書いても最初に初期化される
(loop for x from 1 to 3
      collect (* x a)
      with a = 2)			; => (2 4 6)
;; yは毎回設定される
(loop for x from 1 to 3
      for y = (* x 2)
      collect (list x y))		; => ((1 2) (2 4) (3 6))

;; ローカル変数を作成する
(let ((a 2)
      null)
  (loop for x from 1 to 3
	collect (* x a)
	)
  )					; => (2 4 6)

P217

Emacs Lispテクニックバイブル

Emacs Lispテクニックバイブル